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))
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()))
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
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))
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)))
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()))
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
def _do(timeline): if interaction.outcome_result is None: self.decide(interaction) yield element_utils.run_child(timeline, must_run(self._build_elements(interaction)))
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))
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
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)))
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 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)))
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)))