def get_auto_exit(actors, asm=None, interaction=None, required_actors=()):
    arb_exit = None
    contexts_to_release_all = []
    for actor in actors:
        if actor.is_sim:
            if actor.asm_auto_exit.asm is not None:
                asm_to_exit = actor.asm_auto_exit.asm[0]
                if asm_to_exit is asm:
                    continue
                if required_actors:
                    asm_actors = set(asm_to_exit.actors_gen())
                    if not all(a in asm_actors for a in required_actors):
                        continue
                else:
                    if arb_exit is None:
                        arb_exit = animation.arb.Arb()
                    if interaction is not None:
                        if gsi_handlers.interaction_archive_handlers.is_archive_enabled(interaction):
                            prev_state = asm_to_exit.current_state
                    try:
                        asm_to_exit.request('exit', arb_exit, debug_context=(interaction, asm))
                    finally:
                        if gsi_handlers.interaction_archive_handlers.is_archive_enabled(interaction):
                            gsi_handlers.interaction_archive_handlers.add_animation_data(interaction, asm_to_exit, prev_state, 'exit', 'arb_exit is empty' if arb_exit.empty else arb_exit.get_contents_as_string())
                    contexts_to_release = release_auto_exit(actor)
                    contexts_to_release_all.extend(contexts_to_release)
    release_contexts_fn = get_release_contexts_fn(contexts_to_release_all, AUTO_EXIT_REF_TAG)
    if arb_exit is not None and not arb_exit.empty:
        element = build_critical_section_with_finally(build_critical_section(create_run_animation(arb_exit), flush_all_animations), release_contexts_fn)
        return must_run(element)
    elif contexts_to_release_all:
        return must_run(build_element(release_contexts_fn))
Beispiel #2
0
        def maybe_do_transition(timeline):
            if not use_posture_animations and not exited_carry:
                event_handler_exit_carry(None)
                if callback is not None:
                    callback()
            if use_posture_animations or exited_carry:
                interaction_target_was_target = False
                si_target_was_target = False
                if interaction.target == target:
                    interaction_target_was_target = True
                    interaction.set_target(None)
                if old_carry_posture.target_is_transient and si.target == target:
                    si_target_was_target = True
                    si.set_target(None)
                if carry_system_target is not None:
                    old_carry_posture.carry_system_target = carry_system_target

                def do_transition(timeline):
                    result = yield element_utils.run_child(timeline, transition)
                    if result:
                        interaction_target_was_target = False
                        si_target_was_target = False
                        new_posture.source_interaction = None
                        return True
                    return False

                def post_transition(_):
                    if interaction_target_was_target:
                        interaction.set_target(target)
                    if si_target_was_target:
                        si.set_target(target)
                    if carry_system_target is not None:
                        old_carry_posture.carry_system_target = None

                yield element_utils.run_child(timeline, must_run(build_critical_section_with_finally(do_transition, post_transition)))
Beispiel #3
0
 def _build_outcome_sequence(self, *args, **kwargs):
     sequence = super()._build_outcome_sequence(*args, **kwargs)
     pregnancy_tracker = self.sim.sim_info.pregnancy_tracker
     return element_utils.must_run(
         element_utils.build_critical_section_with_finally(
             self._name_and_create_babies_gen, sequence,
             lambda _: pregnancy_tracker.clear_pregnancy()))
Beispiel #4
0
        def maybe_do_transition_gen(timeline):

            def push_si_gen(timeline):
                context = InteractionContext(sim, InteractionContext.SOURCE_POSTURE_GRAPH, si.priority, run_priority=si.run_priority, insert_strategy=QueueInsertStrategy.NEXT, must_run_next=True, group_id=si.group_id)
                result = new_source_aop.interaction_factory(context)
                if not result:
                    return result
                source_interaction = result.interaction
                new_posture.source_interaction = source_interaction
                owning_interaction = None
                if create_si_fn is not None:
                    (aop, context) = create_si_fn()
                    if aop is not None and context is not None and aop.test(context):
                        result = aop.interaction_factory(context)
                        if result:
                            owning_interaction = result.interaction
                            owning_interaction.acquire_posture_ownership(new_posture)
                            aop.execute_interaction(owning_interaction)
                if owning_interaction is None:
                    si.acquire_posture_ownership(new_posture)
                yield source_interaction.run_direct_gen(timeline)
                return result

            def call_callback(_):
                if callback is not None:
                    callback(new_posture, new_posture.source_interaction)

            if got_callback:
                result = yield element_utils.run_child(timeline, must_run([PostureTransition(new_posture, new_posture_state, context, var_map), push_si_gen, call_callback]))
                return result
            return True
        def maybe_do_transition_gen(timeline):
            def push_si_gen(timeline):
                context = InteractionContext(
                    sim,
                    InteractionContext.SOURCE_POSTURE_GRAPH,
                    si.priority
                    if priority_override is None else priority_override,
                    run_priority=si.run_priority
                    if priority_override is None else priority_override,
                    insert_strategy=QueueInsertStrategy.FIRST,
                    must_run_next=True,
                    group_id=si.group_id)
                result = new_source_aop.interaction_factory(context)
                if not result:
                    return result
                    yield
                source_interaction = result.interaction
                new_posture.source_interaction = source_interaction
                owning_interaction = None
                if create_si_fn is not None:
                    (aop, context) = create_si_fn()
                    if aop is not None:
                        if context is not None:
                            if aop.test(context):
                                result = aop.interaction_factory(context)
                                if result:
                                    owning_interaction = result.interaction
                if owning_interaction is None:
                    si.acquire_posture_ownership(new_posture)
                    yield from source_interaction.run_direct_gen(timeline)
                else:
                    owning_interaction.acquire_posture_ownership(new_posture)
                    aop.execute_interaction(owning_interaction)
                    new_source_aop.execute_interaction(source_interaction)
                if target_posture_state is not None:
                    yield from new_posture.kickstart_linked_carried_posture_gen(
                        timeline)
                return result
                yield

            def call_callback(_):
                if callback is not None:
                    callback(new_posture, new_posture.source_interaction)

            if got_callback:
                if target_posture_state is not None:
                    obj.posture_state = target_posture_state
                result = yield from element_utils.run_child(
                    timeline,
                    must_run([
                        PostureTransition(new_posture, new_posture_state,
                                          context, var_map), push_si_gen,
                        call_callback
                    ]))
                return result
                yield
            return True
            yield
Beispiel #6
0
        def maybe_do_transition(timeline):

            def push_si(_):
                context = InteractionContext(sim, InteractionContext.SOURCE_POSTURE_GRAPH, si.priority, run_priority=si.run_priority, insert_strategy=QueueInsertStrategy.NEXT, must_run_next=True, group_id=si.group_id)
                result = final_source_aop.interaction_factory(context)
                if not result:
                    return result
                final_source_interaction = result.interaction
                si.acquire_posture_ownership(final_posture)
                yield final_source_interaction.run_direct_gen(timeline)
                final_posture.source_interaction = final_source_interaction
                return result

            if not got_callback:
                event_handler_swap_carry(None)
                if callback is not None:
                    callback()
            if original_carry_posture.target_is_transient:
                if interaction.target == original_carry_target:
                    interaction_target_was_target = True
                    interaction.set_target(None)
                else:
                    interaction_target_was_target = False
                if si.target == original_carry_target:
                    si_target_was_target = True
                    si.set_target(None)
                else:
                    si_target_was_target = False
            else:
                interaction_target_was_target = False
                si_target_was_target = False
            if carry_system_target is not None:
                original_carry_posture.carry_system_target = carry_system_target

            def do_transition(timeline):
                nonlocal interaction_target_was_target, si_target_was_target
                result = yield element_utils.run_child(timeline, transition_to_carry_nothing)
                if not result:
                    return False
                interaction_target_was_target = False
                si_target_was_target = False
                carry_nothing_posture.source_interaction = None
                return True

            def post_transition(_):
                if interaction_target_was_target:
                    interaction.set_target(original_carry_target)
                if si_target_was_target:
                    si.set_target(original_carry_target)
                if carry_system_target is not None:
                    original_carry_posture.carry_system_target = None

            exit_carry_result = yield element_utils.run_child(timeline, must_run(build_critical_section_with_finally(do_transition, post_transition)))
            if not (got_callback and exit_carry_result):
                raise RuntimeError('[maxr] Failed to exit carry: {}'.format(original_carry_posture))
            if got_callback:
                context = si.context.clone_for_sim(sim)
                yield element_utils.run_child(timeline, (PostureTransition(final_posture, final_posture_state, context, final_var_map), push_si))
Beispiel #7
0
    def set_up_transition_gen(timeline):
        nonlocal sequence
        (new_posture_state, new_posture, new_source_aop, var_map) = create_enter_carry_posture(sim, sim.posture_state, obj, track)
        got_callback = False

        def event_handler_enter_carry(event_data):
            nonlocal got_callback
            if got_callback:
                logger.warn('Animation({}) calling to start a carry multiple times', event_data.event_data.get('clip_name'))
                return
            got_callback = True
            arb = animation.arb.Arb()
            locked_params = new_posture.get_locked_params(None)
            old_carry_posture = sim.posture_state.get_aspect(track)
            if old_carry_posture is not None:
                old_carry_posture.append_exit_to_arb(arb, new_posture_state, new_posture, var_map)
            new_posture.append_transition_to_arb(arb, old_carry_posture, locked_params=locked_params, in_xevt_handler=True)
            ArbElement(arb).distribute()

        si.animation_context.register_event_handler(event_handler_enter_carry, handler_id=SCRIPT_EVENT_ID_START_CARRY)

        def maybe_do_transition_gen(timeline):

            def push_si_gen(timeline):
                context = InteractionContext(sim, InteractionContext.SOURCE_POSTURE_GRAPH, si.priority, run_priority=si.run_priority, insert_strategy=QueueInsertStrategy.NEXT, must_run_next=True, group_id=si.group_id)
                result = new_source_aop.interaction_factory(context)
                if not result:
                    return result
                source_interaction = result.interaction
                new_posture.source_interaction = source_interaction
                owning_interaction = None
                if create_si_fn is not None:
                    (aop, context) = create_si_fn()
                    if aop is not None and context is not None and aop.test(context):
                        result = aop.interaction_factory(context)
                        if result:
                            owning_interaction = result.interaction
                            owning_interaction.acquire_posture_ownership(new_posture)
                            aop.execute_interaction(owning_interaction)
                if owning_interaction is None:
                    si.acquire_posture_ownership(new_posture)
                yield source_interaction.run_direct_gen(timeline)
                return result

            def call_callback(_):
                if callback is not None:
                    callback(new_posture, new_posture.source_interaction)

            if got_callback:
                result = yield element_utils.run_child(timeline, must_run([PostureTransition(new_posture, new_posture_state, context, var_map), push_si_gen, call_callback]))
                return result
            return True

        sequence = disable_asm_auto_exit(sim, sequence)
        with si.cancel_deferred((si,)):
            yield element_utils.run_child(timeline, must_run(build_critical_section(build_critical_section(sequence, flush_all_animations), maybe_do_transition_gen)))
Beispiel #8
0
 def next_stage(self):
     if self._progress == _StageProgress.Init:
         timeline = services.time_service().sim_timeline
         self._sim.schedule_element(timeline, self)
     if self._progress == _StageProgress.Done:
         raise RuntimeError('StageControllElement is past the point of sleeping')
     if self._wakeable_element is not None:
         raise RuntimeError("Attempting to get an element from next_stage on '{}' before consuming the previous one ({})".format(self, self._progress))
     self._wakeable_element = element_utils.soft_sleep_forever()
     if self._progress != _StageProgress.Sleeping:
         sequence = self._wakeable_element
     else:
         sequence = element_utils.build_element([lambda _: self._wake(), self._wakeable_element])
     sequence = element_utils.return_true_wrapper(element_utils.must_run(sequence))
     return sequence
        def maybe_do_transition_gen(timeline):
            def push_si_gen(timeline):
                context = InteractionContext(
                    sim,
                    InteractionContext.SOURCE_POSTURE_GRAPH,
                    si.priority,
                    run_priority=si.run_priority,
                    insert_strategy=QueueInsertStrategy.NEXT,
                    must_run_next=True,
                    group_id=si.group_id)
                result = new_source_aop.interaction_factory(context)
                if not result:
                    return result
                source_interaction = result.interaction
                new_posture.source_interaction = source_interaction
                owning_interaction = None
                if create_si_fn is not None:
                    (aop, context) = create_si_fn()
                    if aop is not None and context is not None and aop.test(
                            context):
                        result = aop.interaction_factory(context)
                        if result:
                            owning_interaction = result.interaction
                            owning_interaction.acquire_posture_ownership(
                                new_posture)
                            aop.execute_interaction(owning_interaction)
                if owning_interaction is None:
                    si.acquire_posture_ownership(new_posture)
                yield source_interaction.run_direct_gen(timeline)
                return result

            def call_callback(_):
                if callback is not None:
                    callback(new_posture, new_posture.source_interaction)

            if got_callback:
                result = yield element_utils.run_child(
                    timeline,
                    must_run([
                        PostureTransition(new_posture, new_posture_state,
                                          context, var_map), push_si_gen,
                        call_callback
                    ]))
                return result
            return True
        def maybe_do_transition(timeline):
            if not use_posture_animations and not exited_carry:
                event_handler_exit_carry(None)
                if callback is not None:
                    callback()
            if use_posture_animations or exited_carry:
                interaction_target_was_target = False
                si_target_was_target = False
                if interaction.target == target:
                    interaction_target_was_target = True
                    interaction.set_target(None)
                if old_carry_posture.target_is_transient and si.target == target:
                    si_target_was_target = True
                    si.set_target(None)
                if carry_system_target is not None:
                    old_carry_posture.carry_system_target = carry_system_target

                def do_transition(timeline):
                    result = yield element_utils.run_child(
                        timeline, transition)
                    if result:
                        interaction_target_was_target = False
                        si_target_was_target = False
                        new_posture.source_interaction = None
                        return True
                    return False

                def post_transition(_):
                    if interaction_target_was_target:
                        interaction.set_target(target)
                    if si_target_was_target:
                        si.set_target(target)
                    if carry_system_target is not None:
                        old_carry_posture.carry_system_target = None

                yield element_utils.run_child(
                    timeline,
                    must_run(
                        build_critical_section_with_finally(
                            do_transition, post_transition)))
 def _build_outcome_sequence(self, *args, **kwargs):
     sequence = super()._build_outcome_sequence(*args, **kwargs)
     pregnancy_tracker = self.sim.sim_info.pregnancy_tracker
     return element_utils.must_run(element_utils.build_critical_section_with_finally(self._name_and_create_babies_gen, sequence, lambda _: pregnancy_tracker.clear_pregnancy()))
Beispiel #12
0
    def _do_transition(self, timeline) -> bool:
        source = self._source
        dest = self._dest
        sim = dest.sim
        posture_track = dest.track
        starting_position = sim.position

        def do_auto_exit(timeline):
            auto_exit_element = get_auto_exit((sim, ), asm=source.asm)
            if auto_exit_element is not None:
                yield from element_utils.run_child(timeline, auto_exit_element)

        if self._transition_spec is not None and self._transition_spec.portal_obj is not None:
            portal_obj = self._transition_spec.portal_obj
            if self._transition_spec.portal_id is not None:
                new_routing_surface = portal_obj.get_target_surface(
                    self._transition_spec.portal_id)
        elif not dest.unconstrained and dest.target is not None:
            new_routing_surface = dest.target.routing_surface
        elif self._constraint is not None:
            new_routing_surface = self._constraint.routing_surface
        else:
            new_routing_surface = sim.routing_surface
        arb = animation.arb.Arb()
        if dest.external_transition:
            dest_begin = dest.begin(None, self._dest_state, self._context,
                                    new_routing_surface)
            result = yield from element_utils.run_child(
                timeline, must_run(dest_begin))
            return result
            yield
        try:
            sim.active_transition = self
            posture_idle_started = False

            def start_posture_idle(*_, **__):
                nonlocal posture_idle_started
                if posture_idle_started:
                    return
                dest.log_info('Idle')
                posture_idle_started = True
                idle_arb = animation.arb.Arb()
                dest.append_idle_to_arb(idle_arb)
                distribute_arb_element(idle_arb, master=sim)

            arb.register_event_handler(start_posture_idle,
                                       handler_id=self.IDLE_TRANSITION_XEVT)
            if self._transition_spec is not None:
                if sim.posture.mobile and self._transition_spec.path is not None:
                    yield from element_utils.run_child(timeline, do_auto_exit)
                    result = yield from self.do_transition_route(
                        timeline, sim, source, dest)
                    if not result:
                        if self._transition_spec.is_failure_path:
                            (
                                failure_reason, failure_target
                            ) = sim.transition_controller.get_failure_reason_and_target(
                                sim)
                            if failure_reason is not None or failure_target is not None:
                                if self._interaction is not None:
                                    yield from element_utils.run_child(
                                        timeline,
                                        handle_transition_failure(
                                            sim,
                                            self._interaction.target,
                                            self._interaction,
                                            failure_reason=failure_reason,
                                            failure_object_id=failure_target))
                                sim.transition_controller.cancel(
                                    cancel_reason_msg=
                                    'Transition canceled due to successful route failure.'
                                )
                        return result
                        yield
                else:
                    result = self._transition_spec.do_reservation(sim)
                    if not result:
                        return result
                        yield
            if source is dest:
                sim.on_posture_event(PostureEvent.POSTURE_CHANGED,
                                     self._dest_state, dest.track, source,
                                     dest)
                return TestResult.TRUE
                yield
            self._status = self.Status.ANIMATING
            source_locked_params = frozendict()
            dest_locked_params = frozendict()
            if self._transition_spec is not None:
                source_locked_params = self._transition_spec.locked_params
                dest_locked_params = self._transition_spec.locked_params
            dest_posture_spec = None
            import services
            zone = services.current_zone()
            fire_service = services.get_fire_service()
            lot_on_fire = fire_service.fire_is_active
            distance_param = PostureTransition.calculate_distance_param(
                source.target, dest.target)
            if self._transition_spec is not None:
                if dest.track == PostureTrack.BODY:
                    if not source.mobile:
                        source_locked_params += {'onFire': lot_on_fire}
                        if distance_param is not None:
                            source_locked_params += {
                                'distance': distance_param
                            }
                    if not dest.mobile:
                        dest_locked_params += {'onFire': lot_on_fire}
                        if self._interaction is not None:
                            transition_asm_params = sim.get_transition_asm_params(
                            )
                            dest_locked_params += transition_asm_params
                            source_locked_params += transition_asm_params
                        if distance_param is not None:
                            dest_locked_params += {'distance': distance_param}
                    elif self._transition_spec.portal_obj is not None:
                        transition_asm_params = sim.get_transition_asm_params()
                        dest_locked_params += transition_asm_params
                        source_locked_params += transition_asm_params
                    transition_global_asm_params = sim.get_transition_global_asm_params(
                    )
                    dest_locked_params += transition_global_asm_params
                    source_locked_params += transition_global_asm_params
                    dest_posture_spec = self._transition_spec.posture_spec
            source_locked_params += self._locked_params
            dest_locked_params += self._locked_params
            if self._transition_spec is not None and self._transition_spec.portal_obj is not None:
                target_override = self._transition_spec.portal_obj
                portal_params = self._transition_spec.portal_obj.get_portal_asm_params(
                    self._transition_spec.portal_id, sim)
                source_locked_params += portal_params
                dest_locked_params += portal_params
            else:
                target_override = None

            def do_transition_animation(timeline):
                yield from element_utils.run_child(timeline, do_auto_exit)
                if PostureTrack.is_carry(
                        dest.track
                ) and dest.target is not None and dest.target.is_sim:
                    auto_exit_element = get_auto_exit((dest.target, ),
                                                      asm=source.asm)
                    if auto_exit_element is not None:
                        yield from element_utils.run_child(
                            timeline, auto_exit_element)
                source.append_exit_to_arb(arb,
                                          self._dest_state,
                                          dest,
                                          self._var_map,
                                          locked_params=source_locked_params,
                                          target_override=target_override)
                dest.append_transition_to_arb(arb,
                                              source,
                                              locked_params=dest_locked_params,
                                              posture_spec=dest_posture_spec,
                                              target_override=target_override)
                dest_begin = dest.begin(arb, self._dest_state, self._context,
                                        new_routing_surface)
                result = yield from element_utils.run_child(
                    timeline, [do_auto_exit, dest_begin])
                return result
                yield

            sequence = (do_transition_animation, )
            from carry.carry_utils import interact_with_carried_object, holster_carried_object, maybe_holster_objects_through_sequence
            if dest.track.is_carry(dest.track):
                if dest.target is not None:
                    carry_target = dest.target
                    carry_posture_state = self._dest_state
                    carry_animation_context = dest.asm.context
                else:
                    carry_target = source.target
                    carry_posture_state = sim.posture_state
                    carry_animation_context = source.asm.context
                sequence = interact_with_carried_object(
                    sim,
                    carry_target,
                    posture_state=carry_posture_state,
                    interaction=dest.source_interaction,
                    animation_context=carry_animation_context,
                    sequence=sequence)
            if sim.is_required_to_holster_for_transition(source, dest):
                sequence = maybe_holster_objects_through_sequence(
                    sim,
                    sequence=sequence,
                    unholster_after_predicate=self.
                    _get_unholster_after_predicate(sim,
                                                   dest.source_interaction))
            else:
                sequence = holster_carried_object(
                    sim,
                    dest.source_interaction,
                    self._get_unholster_predicate(sim,
                                                  dest.source_interaction),
                    flush_before_sequence=True,
                    sequence=sequence)
            sequence = dest.add_transition_extras(sequence, arb=arb)
            mutex_key = self.get_entry_exit_mutex_key()
            if mutex_key is not None:
                sequence = mutex.with_mutex(
                    mutex_key, element_utils.build_element(sequence))
            sis = set()
            sis.add(source.source_interaction)
            sis.add(dest.source_interaction)
            sis.update(source.owning_interactions)
            sis.update(dest.owning_interactions)
            for si in sis:
                if si is None:
                    continue
                with si.cancel_deferred(sis):
                    result = yield from element_utils.run_child(
                        timeline, must_run(sequence))
                break
            else:
                result = yield from element_utils.run_child(
                    timeline, must_run(sequence))
            if result:
                start_posture_idle()
            yield from sim.si_state.process_gen(timeline)
        finally:
            sim.active_transition = None
            self._status = self.Status.FINISHED
            if self._transition_spec is not None:
                self._transition_spec.release_additional_reservation_handlers()
                self._transition_spec.remove_props_created_to_reserve_slots(
                    sim)
                if self._transition_spec.portal_obj is not None:
                    self._transition_spec.portal_obj.clear_portal_cost_override(
                        self._transition_spec.portal_id, sim=sim)
        if sim.posture_state.get_aspect(posture_track) is not dest:
            logger.debug(
                "{}: _do_transition failed: after transition Sim's posture state aspect isn't destination posture."
            )
            if dest.source_interaction is not None:
                dest.source_interaction.cancel(
                    FinishingType.TRANSITION_FAILURE,
                    cancel_reason_msg='Transition canceled during transition.')
            return TestResult(
                False,
                "After transition Sim's posture state aspect isn't destination posture."
            )
            yield
        if not dest.unconstrained and not not (
                sim.transition_controller is not None
                and sims4.math.vector3_almost_equal(
                    sim.position,
                    starting_position,
                    epsilon=sims4.geometry.ANIMATION_SLOT_EPSILON)):
            sim.transition_controller.release_stand_slot_reservations((sim, ))
        return TestResult.TRUE
        yield
Beispiel #13
0
 def _do(timeline):
     if interaction.outcome_result is None:
         self.decide(interaction)
     yield element_utils.run_child(timeline, must_run(self._build_elements(interaction)))
Beispiel #14
0
        def maybe_do_transition(timeline):
            def push_si(_):
                context = InteractionContext(
                    sim,
                    InteractionContext.SOURCE_POSTURE_GRAPH,
                    si.priority,
                    run_priority=si.run_priority,
                    insert_strategy=QueueInsertStrategy.NEXT,
                    must_run_next=True,
                    group_id=si.group_id)
                result = final_source_aop.interaction_factory(context)
                if not result:
                    return result
                    yield
                final_source_interaction = result.interaction
                si.acquire_posture_ownership(final_posture)
                yield from final_source_interaction.run_direct_gen(timeline)
                final_posture.source_interaction = final_source_interaction
                return result
                yield

            if not got_callback:
                event_handler_swap_carry(None)
                if callback is not None:
                    callback()
            if got_callback:
                if original_carry_posture.target_is_transient:
                    if interaction.target == original_carry_target:
                        interaction_target_was_target = True
                        interaction.set_target(None)
                    else:
                        interaction_target_was_target = False
                    if si.target == original_carry_target:
                        si_target_was_target = True
                        si.set_target(None)
                    else:
                        si_target_was_target = False
                else:
                    interaction_target_was_target = False
                    si_target_was_target = False
                if carry_system_target is not None:
                    original_carry_posture.carry_system_target = carry_system_target

                def do_transition(timeline):
                    nonlocal interaction_target_was_target, si_target_was_target
                    result = yield from element_utils.run_child(
                        timeline, transition_to_carry_nothing)
                    if not result:
                        return False
                        yield
                    interaction_target_was_target = False
                    si_target_was_target = False
                    carry_nothing_posture.source_interaction = None
                    return True
                    yield

                def post_transition(_):
                    if interaction_target_was_target:
                        interaction.set_target(original_carry_target)
                    if si_target_was_target:
                        si.set_target(original_carry_target)
                    if carry_system_target is not None:
                        original_carry_posture.carry_system_target = None

                exit_carry_result = yield from element_utils.run_child(
                    timeline,
                    must_run(
                        build_critical_section_with_finally(
                            do_transition, post_transition)))
                if not exit_carry_result:
                    raise RuntimeError(
                        '[maxr] Failed to exit carry: {}'.format(
                            original_carry_posture))
            if got_callback:
                context = si.context.clone_for_sim(sim)
                yield from element_utils.run_child(
                    timeline,
                    (PostureTransition(final_posture, final_posture_state,
                                       context, final_var_map), push_si))
Beispiel #15
0
    def _do_transition(self, timeline) -> bool:
        source = self._source
        dest = self._dest
        sim = dest.sim
        posture_track = dest.track
        starting_position = sim.position

        def do_auto_exit(timeline):
            auto_exit_element = get_auto_exit((sim,), asm=source.asm)
            if auto_exit_element is not None:
                yield element_utils.run_child(timeline, auto_exit_element)

        arb = animation.arb.Arb()
        if dest.external_transition:
            dest_begin = dest.begin(None, self._dest_state, self._context)
            result = yield element_utils.run_child(timeline, must_run(dest_begin))
            return result
        try:
            sim.active_transition = self
            posture_idle_started = False

            def start_posture_idle(*_, **__):
                nonlocal posture_idle_started
                if posture_idle_started:
                    return
                dest.log_info('Idle')
                posture_idle_started = True
                idle_arb = animation.arb.Arb()
                dest.append_idle_to_arb(idle_arb)
                ArbElement(idle_arb, master=sim).distribute()

            arb.register_event_handler(start_posture_idle, handler_id=self.IDLE_TRANSITION_XEVT)
            if sim.posture.mobile and self._transition_spec.path is not None:
                yield element_utils.run_child(timeline, do_auto_exit)
                result = yield self.do_transition_route(timeline, sim, source, dest)
                if not result:
                    return result
            else:
                result = self._transition_spec.do_reservation(sim)
                if not result:
                    return result
            if self._transition_spec is not None and self._transition_spec.portal is not None:
                portal_transition = self._transition_spec.portal.get_portal_element(sim)
                yield element_utils.run_child(timeline, portal_transition)
            if source is dest:
                sim.on_posture_event(PostureEvent.POSTURE_CHANGED, self._dest_state, dest.track, source, dest)
                return TestResult.TRUE
            self._status = self.Status.ANIMATING
            source_locked_params = frozendict()
            dest_locked_params = frozendict()
            dest_posture_spec = None
            if self._transition_spec is not None and dest.track == PostureTrack.BODY:
                if not source.mobile:
                    source_locked_params = self._transition_spec.locked_params
                if not dest.mobile:
                    dest_locked_params = self._transition_spec.locked_params
                    if self._interaction is not None:
                        dest_locked_params += self._interaction.transition_asm_params
                dest_posture_spec = self._transition_spec.posture_spec

            def do_transition_animation(timeline):
                yield element_utils.run_child(timeline, do_auto_exit)
                source.append_exit_to_arb(arb, self._dest_state, dest, self._var_map, locked_params=source_locked_params)
                dest.append_transition_to_arb(arb, source, locked_params=dest_locked_params, posture_spec=dest_posture_spec)
                dest_begin = dest.begin(arb, self._dest_state, self._context)
                result = yield element_utils.run_child(timeline, [do_auto_exit, dest_begin])
                return result

            sequence = (do_transition_animation,)
            from carry import interact_with_carried_object, holster_carried_object
            if dest.track.is_carry(dest.track):
                if dest.target is not None:
                    carry_target = dest.target
                    carry_posture_state = self._dest_state
                    carry_animation_context = dest.asm.context
                else:
                    carry_target = source.target
                    carry_posture_state = sim.posture_state
                    carry_animation_context = source.asm.context
                sequence = interact_with_carried_object(sim, carry_target, posture_state=carry_posture_state, interaction=dest.source_interaction, animation_context=carry_animation_context, sequence=sequence)
            sequence = holster_carried_object(sim, dest.source_interaction, self._get_unholster_predicate(sim, dest.source_interaction), flush_before_sequence=True, sequence=sequence)
            sequence = dest.add_transition_extras(sequence)
            sis = set()
            sis.add(source.source_interaction)
            sis.add(dest.source_interaction)
            sis.update(source.owning_interactions)
            sis.update(dest.owning_interactions)
            for si in sis:
                if si is None:
                    pass
                with si.cancel_deferred(sis):
                    result = yield element_utils.run_child(timeline, must_run(sequence))
                break
            result = yield element_utils.run_child(timeline, must_run(sequence))
            if result:
                start_posture_idle()
            yield sim.si_state.process_gen(timeline)
        finally:
            sim.active_transition = None
            self._status = self.Status.FINISHED
            if self._transition_spec is not None:
                self._transition_spec.release_additional_reservation_handlers()
                self._transition_spec.remove_props_created_to_reserve_slots(sim)
        if sim.posture_state.get_aspect(posture_track) is not dest:
            logger.debug("{}: _do_transition failed: after transition Sim's posture state aspect isn't destination posture.")
            if dest.source_interaction is not None:
                dest.source_interaction.cancel(FinishingType.TRANSITION_FAILURE, cancel_reason_msg='Transition canceled during transition.')
            return TestResult(False, "After transition Sim's posture state aspect isn't destination posture.")
        if not dest.unconstrained and sim.transition_controller is not None and not sims4.math.vector3_almost_equal(sim.position, starting_position, epsilon=sims4.geometry.ANIMATION_SLOT_EPSILON):
            sim.transition_controller.release_stand_slot_reservations((sim,))
        return TestResult.TRUE
Beispiel #16
0
        def maybe_do_transition(timeline):
            nonlocal transition
            (_, _, _, new_transition,
             _) = _create_exit_carry_posture(sim,
                                             target,
                                             interaction,
                                             use_posture_animations,
                                             preserve_posture=new_posture)
            if new_transition is not None:
                transition = new_transition
            if not use_posture_animations and not exited_carry:
                event_handler_exit_carry(None)
                if callback is not None:
                    callback()
            if use_posture_animations or exited_carry:
                interaction_target_was_target = False
                si_target_was_target = False
                if old_carry_posture.target_is_transient:
                    if interaction.target == target:
                        interaction_target_was_target = True
                        interaction.set_target(None)
                    if si.target == target:
                        si_target_was_target = True
                        si.set_target(None)
                if carry_system_target is not None:
                    old_carry_posture.carry_system_target = carry_system_target

                def do_transition(timeline):
                    result = yield from element_utils.run_child(
                        timeline, transition)
                    if result:
                        if target.is_sim:
                            body_posture_type = sim.posture_state.spec.body.posture_type
                            if not body_posture_type.multi_sim:
                                post_transition_spec = sim.posture_state.spec.clone(
                                    body=PostureAspectBody(
                                        (body_posture_type, None)),
                                    surface=PostureAspectSurface(
                                        (None, None, None)))
                                post_posture_state = PostureState(
                                    sim, sim.posture_state,
                                    post_transition_spec, var_map)
                                post_posture_state.body.source_interaction = sim.posture.source_interaction
                                post_transition = PostureTransition(
                                    post_posture_state.body,
                                    post_posture_state,
                                    sim.posture.posture_context, var_map)
                                post_transition.must_run = True
                                yield from element_utils.run_child(
                                    timeline, post_transition)
                        interaction_target_was_target = False
                        si_target_was_target = False
                        new_posture.source_interaction = None
                        return True
                        yield
                    return False
                    yield

                def post_transition(_):
                    if interaction_target_was_target:
                        interaction.set_target(target)
                    if si_target_was_target:
                        si.set_target(target)
                    if carry_system_target is not None:
                        old_carry_posture.carry_system_target = None

                yield from element_utils.run_child(
                    timeline,
                    must_run(
                        build_critical_section_with_finally(
                            do_transition, post_transition)))
Beispiel #17
0
 def _stage(self):
     self._sleeping_element = element_utils.soft_sleep_forever()
     stage_element = element_utils.build_critical_section_with_finally(self._set_suspended, self._sleeping_element, self._end_suspended)
     return element_utils.return_true_wrapper(element_utils.must_run(stage_element))
Beispiel #18
0
    def set_up_transition_gen(timeline):
        nonlocal obj, sequence
        if carry_obj_participant_type is not None:
            obj = si.get_participant(carry_obj_participant_type)
            if obj is None:
                raise ValueError(
                    '[rmccord] Attempt to perform an enter carry while holding with None as the carried object. SI: {}'
                    .format(si))
        (new_posture_state, new_posture, new_source_aop,
         var_map) = _create_enter_carry_posture(sim, sim.posture_state, obj,
                                                track)
        if obj.is_sim:
            target_posture_state = new_posture.set_target_linked_posture_data()
        else:
            target_posture_state = None
        got_callback = False

        def event_handler_enter_carry(event_data):
            nonlocal got_callback
            if got_callback:
                logger.warn(
                    'Animation({}) calling to start a carry multiple times',
                    event_data.event_data.get('clip_name'))
                return
            got_callback = True
            arb = Arb()
            locked_params = new_posture.get_locked_params(None)
            old_carry_posture = sim.posture_state.get_aspect(track)
            if old_carry_posture is not None:
                old_carry_posture.append_exit_to_arb(arb, new_posture_state,
                                                     new_posture, var_map)
            new_posture.append_transition_to_arb(arb,
                                                 old_carry_posture,
                                                 locked_params=locked_params,
                                                 in_xevt_handler=True)
            distribute_arb_element(arb)

        if asm_context is not None:
            asm_context.register_event_handler(
                event_handler_enter_carry,
                handler_type=ClipEventType.Script,
                handler_id=SCRIPT_EVENT_ID_START_CARRY,
                tag='enter_carry')
        else:
            si.store_event_handler(event_handler_enter_carry,
                                   handler_id=SCRIPT_EVENT_ID_START_CARRY)

        def maybe_do_transition_gen(timeline):
            def push_si_gen(timeline):
                context = InteractionContext(
                    sim,
                    InteractionContext.SOURCE_POSTURE_GRAPH,
                    si.priority
                    if priority_override is None else priority_override,
                    run_priority=si.run_priority
                    if priority_override is None else priority_override,
                    insert_strategy=QueueInsertStrategy.FIRST,
                    must_run_next=True,
                    group_id=si.group_id)
                result = new_source_aop.interaction_factory(context)
                if not result:
                    return result
                    yield
                source_interaction = result.interaction
                new_posture.source_interaction = source_interaction
                owning_interaction = None
                if create_si_fn is not None:
                    (aop, context) = create_si_fn()
                    if aop is not None:
                        if context is not None:
                            if aop.test(context):
                                result = aop.interaction_factory(context)
                                if result:
                                    owning_interaction = result.interaction
                if owning_interaction is None:
                    si.acquire_posture_ownership(new_posture)
                    yield from source_interaction.run_direct_gen(timeline)
                else:
                    owning_interaction.acquire_posture_ownership(new_posture)
                    aop.execute_interaction(owning_interaction)
                    new_source_aop.execute_interaction(source_interaction)
                if target_posture_state is not None:
                    yield from new_posture.kickstart_linked_carried_posture_gen(
                        timeline)
                return result
                yield

            def call_callback(_):
                if callback is not None:
                    callback(new_posture, new_posture.source_interaction)

            if got_callback:
                if target_posture_state is not None:
                    obj.posture_state = target_posture_state
                result = yield from element_utils.run_child(
                    timeline,
                    must_run([
                        PostureTransition(new_posture, new_posture_state,
                                          context, var_map), push_si_gen,
                        call_callback
                    ]))
                return result
                yield
            return True
            yield

        sequence = disable_asm_auto_exit(sim, sequence)
        with si.cancel_deferred((si, )):
            yield from element_utils.run_child(
                timeline,
                must_run(
                    build_critical_section(
                        build_critical_section(sequence, flush_all_animations),
                        maybe_do_transition_gen)))
Beispiel #19
0
 def _stage(self):
     self._sleeping_element = element_utils.soft_sleep_forever()
     stage_element = element_utils.build_critical_section_with_finally(
         self._set_suspended, self._sleeping_element, self._end_suspended)
     return element_utils.return_true_wrapper(
         element_utils.must_run(stage_element))
    def set_up_transition_gen(timeline):
        nonlocal sequence
        (new_posture_state, new_posture, new_source_aop,
         var_map) = create_enter_carry_posture(sim, sim.posture_state, obj,
                                               track)
        got_callback = False

        def event_handler_enter_carry(event_data):
            nonlocal got_callback
            if got_callback:
                logger.warn(
                    'Animation({}) calling to start a carry multiple times',
                    event_data.event_data.get('clip_name'))
                return
            got_callback = True
            arb = animation.arb.Arb()
            locked_params = new_posture.get_locked_params(None)
            old_carry_posture = sim.posture_state.get_aspect(track)
            if old_carry_posture is not None:
                old_carry_posture.append_exit_to_arb(arb, new_posture_state,
                                                     new_posture, var_map)
            new_posture.append_transition_to_arb(arb,
                                                 old_carry_posture,
                                                 locked_params=locked_params,
                                                 in_xevt_handler=True)
            ArbElement(arb).distribute()

        si.animation_context.register_event_handler(
            event_handler_enter_carry, handler_id=SCRIPT_EVENT_ID_START_CARRY)

        def maybe_do_transition_gen(timeline):
            def push_si_gen(timeline):
                context = InteractionContext(
                    sim,
                    InteractionContext.SOURCE_POSTURE_GRAPH,
                    si.priority,
                    run_priority=si.run_priority,
                    insert_strategy=QueueInsertStrategy.NEXT,
                    must_run_next=True,
                    group_id=si.group_id)
                result = new_source_aop.interaction_factory(context)
                if not result:
                    return result
                source_interaction = result.interaction
                new_posture.source_interaction = source_interaction
                owning_interaction = None
                if create_si_fn is not None:
                    (aop, context) = create_si_fn()
                    if aop is not None and context is not None and aop.test(
                            context):
                        result = aop.interaction_factory(context)
                        if result:
                            owning_interaction = result.interaction
                            owning_interaction.acquire_posture_ownership(
                                new_posture)
                            aop.execute_interaction(owning_interaction)
                if owning_interaction is None:
                    si.acquire_posture_ownership(new_posture)
                yield source_interaction.run_direct_gen(timeline)
                return result

            def call_callback(_):
                if callback is not None:
                    callback(new_posture, new_posture.source_interaction)

            if got_callback:
                result = yield element_utils.run_child(
                    timeline,
                    must_run([
                        PostureTransition(new_posture, new_posture_state,
                                          context, var_map), push_si_gen,
                        call_callback
                    ]))
                return result
            return True

        sequence = disable_asm_auto_exit(sim, sequence)
        with si.cancel_deferred((si, )):
            yield element_utils.run_child(
                timeline,
                must_run(
                    build_critical_section(
                        build_critical_section(sequence, flush_all_animations),
                        maybe_do_transition_gen)))