def run_subaction_autonomy(self): if not SubActionAutonomy.test(self.owner): if gsi_handlers.autonomy_handlers.archiver.enabled: gsi_handlers.autonomy_handlers.archive_autonomy_data(self.owner, 'None - Autonomy Disabled', 'SubActionAutonomy', gsi_handlers.autonomy_handlers.EMPTY_ARCHIVE) return EnqueueResult.NONE attempt_to_use_cache = False if gsi_handlers.autonomy_handlers.archiver.enabled: caching_info = [] else: caching_info = None while self._cached_mixer_interactions: attempt_to_use_cache = True interaction_to_run = self._cached_mixer_interactions.pop(0) if self._should_run_cached_interaction(interaction_to_run): enqueue_result = AffordanceObjectPair.execute_interaction(interaction_to_run) if enqueue_result: if gsi_handlers.autonomy_handlers.archiver.enabled: gsi_handlers.autonomy_handlers.archive_autonomy_data(self.owner, 'Using Cache: {}'.format(interaction_to_run), 'SubActionAutonomy', gsi_handlers.autonomy_handlers.EMPTY_ARCHIVE) return enqueue_result if interaction_to_run: interaction_to_run.invalidate() while caching_info is not None: caching_info.append('Failed to use cache interaction: {}'.format(interaction_to_run)) continue if caching_info is not None and attempt_to_use_cache: caching_info.append('Cache invalid:Regenerating') self.invalidate_mixer_interaction_cache(None) context = InteractionContext(self.owner, InteractionSource.AUTONOMY, Priority.Low) autonomy_request = AutonomyRequest(self.owner, context=context, consider_scores_of_zero=True, autonomy_mode=SubActionAutonomy) if caching_info is not None: caching_info.append('Caching: Mixers - START') initial_probability_result = None while len(self._cached_mixer_interactions) < self.MIXERS_TO_CACHE: interaction = services.autonomy_service().find_best_action(autonomy_request, consider_all_options=True, archive_if_enabled=False) if interaction is None: break if caching_info is not None: caching_info.append('caching interaction: {}'.format(interaction)) if initial_probability_result is None: initial_probability_result = list(autonomy_request.gsi_data['Probability']) self._cached_mixer_interactions.append(interaction) if caching_info is not None: caching_info.append('Caching: Mixers - DONE') if self._cached_mixer_interactions: interaction = self._cached_mixer_interactions.pop(0) if caching_info is not None: caching_info.append('Executing mixer: {}'.format(interaction)) enqueue_result = AffordanceObjectPair.execute_interaction(interaction) if caching_info is not None: autonomy_request.gsi_data['caching_info'] = caching_info autonomy_request.gsi_data['Probability'] = initial_probability_result if enqueue_result: result_info = str(interaction) else: result_info = 'None - failed to execute: {}'.format(interaction) gsi_handlers.autonomy_handlers.archive_autonomy_data(autonomy_request.sim, result_info, autonomy_request.autonomy_mode_label, autonomy_request.gsi_data) return enqueue_result return EnqueueResult.NONE
def _do_perform_gen(self, timeline): sim = self.get_participant(self.sim_to_push_affordance_on) if sim == self.context.sim: context = self.context.clone_for_continuation(self) else: context = context.clone_for_sim(sim) max_priority = None aops_valid = [] for (priority, aop) in self._aops_sorted_gen(self.target, **self.interaction_parameters): if max_priority is not None and priority < max_priority: break if aop.test(context): aops_valid.append(aop) max_priority = priority if not aops_valid: raise RuntimeError('Failed to find valid super affordance in AggregateSuperInteraction, did we not run its test immediately before executing it? [jpollak]') interactions_by_distance = [] for aop in aops_valid: interaction_result = aop.interaction_factory(context) if not interaction_result: raise RuntimeError('Failed to generate interaction from aop {}. {} [maxr/tastle]'.format(aop, interaction_result)) interaction = interaction_result.interaction if len(aops_valid) == 1: distance = 0 else: (distance, _, _) = interaction.estimate_distance() if distance is not None: interactions_by_distance.append((distance, interaction)) (_, interaction) = max(interactions_by_distance, key=operator.itemgetter(0)) return AffordanceObjectPair.execute_interaction(interaction) yield None
def _run_interaction_gen(self, timeline): target_sim = self.get_participant( interactions.ParticipantType.TargetSim) logger.assert_log( target_sim is not None, 'target_sim is invalid in SocialPickerSuperInteraction._run_interaction_gen()', owner='rez') self.force_inertial = True context = self.context.clone_for_sim( self.sim, bucket=InteractionBucketType.BASED_ON_SOURCE) autonomy_request = AutonomyRequest( self.sim, autonomy_mode=autonomy.autonomy_modes.SocialAutonomy, static_commodity_list=[self.SOCIAL_STATIC_COMMODITY], object_list=[target_sim], context=context, push_super_on_prepare=True, consider_scores_of_zero=True) social_mixer = services.autonomy_service().find_best_action( autonomy_request) if social_mixer: if not social_mixer.super_interaction.running: social_mixer.super_interaction = None for si in autonomy_request.interactions_to_invalidate: si.invalidate() autonomy_request.interactions_to_invalidate.clear() if social_mixer: social_mixer.push_super_affordance_target = target_sim return AffordanceObjectPair.execute_interaction(social_mixer) yield else: return event_testing.results.EnqueueResult.NONE yield
def _make_guests_watch(self, _): static_commodity_list = [ self.owner.guest.watch_wedding_static_commodity ] object_list = list( self.owner.all_sims_in_job_gen(self.owner.betrothed.situation_job)) for sim_info in tuple(self._guest_sim_infos_to_force_watch): sim = sim_info.get_sim_instance() if sim is None: self._guest_sim_infos_to_force_watch.remove(sim_info) InteractionCancelCompatibility.cancel_interactions_for_reason( sim, InteractionCancelReason.WEDDING, FinishingType.WEDDING, 'Interaction was cancelled due to the wedding situation.') autonomy_request = AutonomyRequest( sim, autonomy_mode=FullAutonomy, object_list=object_list, static_commodity_list=static_commodity_list, limited_autonomy_allowed=False, autonomy_mode_label_override='WeddingMakeGuestsWatch') selected_interaction = services.autonomy_service( ).find_best_action(autonomy_request) while selected_interaction is not None: if AffordanceObjectPair.execute_interaction( selected_interaction): self._guest_sim_infos_to_force_watch.remove(sim_info) if self._guest_sim_infos_to_force_watch: self._alarm_handle = alarms.add_alarm( self, create_time_span(minutes=self.MAKE_GUESTS_WATCH_ALARM_TIME), self._make_guests_watch)
def _push_interaction(self, selected_interaction): should_log = services.autonomy_service().should_log(self.owner) if AffordanceObjectPair.execute_interaction(selected_interaction): return True if should_log: logger.debug('Autonomy failed to push {}', selected_interaction.affordance) if selected_interaction.target: self.owner.add_lockout(selected_interaction.target, AutonomyMode.LOCKOUT_TIME) return False
def _do_perform_gen(self, timeline): sim = self.get_participant(self.sim_to_push_affordance_on) if sim == self.context.sim: context = self.context.clone_for_continuation(self) else: context = context.clone_for_sim(sim) max_priority = None aops_valid = [] self._valid_aops = None valid_aops = self._get_tested_aops(self.target, context, **self.interaction_parameters) for (aop, priority) in valid_aops: if max_priority is not None: if priority < max_priority: break aops_valid.append(aop) max_priority = priority if not aops_valid: logger.warn( 'Failed to find valid super affordance in AggregateSuperInteraction: {}, did we not run its test immediately before executing it?', self) return ExecuteResult.NONE yield compatible_interactions = [] for aop in aops_valid: interaction_result = aop.interaction_factory(context) if not interaction_result: raise RuntimeError( 'Failed to generate interaction from aop {}. {} [rmccord]'. format(aop, interaction_result)) interaction = interaction_result.interaction if self.use_aggregated_affordance_constraints: if interactions.si_state.SIState.test_compatibility( interaction, force_concrete=True): compatible_interactions.append(interaction) compatible_interactions.append(interaction) if not compatible_interactions: return ExecuteResult.NONE yield interactions_by_distance = [] for interaction in compatible_interactions: if len(compatible_interactions) == 1: distance = 0 else: (distance, _, _) = interaction.estimate_distance() if distance is not None: interactions_by_distance.append((distance, interaction)) else: interactions_by_distance.append( (sims4.math.MAX_INT32, interaction)) (_, interaction) = min(interactions_by_distance, key=operator.itemgetter(0)) return AffordanceObjectPair.execute_interaction(interaction) yield
def _push_interaction(self, selected_interaction): should_log = services.autonomy_service().should_log(self.owner) if AffordanceObjectPair.execute_interaction(selected_interaction): return True if should_log: logger.debug('Autonomy failed to push {}', selected_interaction.affordance) if selected_interaction.target: self.owner.add_lockout(selected_interaction.target, AutonomyMode.LOCKOUT_TIME) return False
def activate(cls): client = services.client_manager().get_first_client() active_sim = client.active_sim if cls.gameplay_immediate_test is not None: resolver = event_testing.resolver.SingleSimResolver(active_sim.sim_info) if resolver(cls.gameplay_immediate_test): cls.satisfy() else: return for buff_ref in cls.buffs: active_sim.add_buff_from_op(buff_ref.buff_type, buff_reason=buff_ref.buff_reason) if cls.gameplay_test is not None: services.get_event_manager().register_tests(cls, [cls.gameplay_test]) if cls.commodities_to_solve: context = InteractionContext(active_sim, InteractionContext.SOURCE_SCRIPT_WITH_USER_INTENT, priority.Priority.High, bucket=InteractionBucketType.DEFAULT) for commodity in cls.commodities_to_solve: if not active_sim.queue.can_queue_visible_interaction(): break autonomy_request = autonomy.autonomy_request.AutonomyRequest(active_sim, autonomy_mode=autonomy.autonomy_modes.FullAutonomy, commodity_list=(commodity,), context=context, consider_scores_of_zero=True, posture_behavior=AutonomyPostureBehavior.IGNORE_SI_STATE, distance_estimation_behavior=AutonomyDistanceEstimationBehavior.ALLOW_UNREACHABLE_LOCATIONS, allow_opportunity_cost=False, autonomy_mode_label_override='Tutorial') selected_interaction = services.autonomy_service().find_best_action(autonomy_request) AffordanceObjectPair.execute_interaction(selected_interaction)
def activate(cls): client = services.client_manager().get_first_client() active_sim = client.active_sim if cls.gameplay_immediate_test is not None: resolver = event_testing.resolver.SingleSimResolver( active_sim.sim_info) if resolver(cls.gameplay_immediate_test): cls.satisfy() else: return for buff_ref in cls.buffs: active_sim.add_buff_from_op(buff_ref.buff_type, buff_reason=buff_ref.buff_reason) if cls.gameplay_test is not None: services.get_event_manager().register_tests( cls, [cls.gameplay_test]) if cls.commodities_to_solve: context = InteractionContext( active_sim, InteractionContext.SOURCE_SCRIPT_WITH_USER_INTENT, priority.Priority.High, bucket=InteractionBucketType.DEFAULT) for commodity in cls.commodities_to_solve: if not active_sim.queue.can_queue_visible_interaction(): break autonomy_request = autonomy.autonomy_request.AutonomyRequest( active_sim, autonomy_mode=autonomy.autonomy_modes.FullAutonomy, commodity_list=(commodity, ), context=context, consider_scores_of_zero=True, posture_behavior=AutonomyPostureBehavior.IGNORE_SI_STATE, distance_estimation_behavior= AutonomyDistanceEstimationBehavior. ALLOW_UNREACHABLE_LOCATIONS, allow_opportunity_cost=False, autonomy_mode_label_override='Tutorial') selected_interaction = services.autonomy_service( ).find_best_action(autonomy_request) AffordanceObjectPair.execute_interaction(selected_interaction)
def _make_guests_watch(self, _): static_commodity_list = [self.owner.guest.watch_wedding_static_commodity] object_list = list(self.owner.all_sims_in_job_gen(self.owner.betrothed.situation_job)) for sim_info in tuple(self._guest_sim_infos_to_force_watch): sim = sim_info.get_sim_instance() if sim is None: self._guest_sim_infos_to_force_watch.remove(sim_info) InteractionCancelCompatibility.cancel_interactions_for_reason(sim, InteractionCancelReason.WEDDING, FinishingType.WEDDING, 'Interaction was cancelled due to the wedding situation.') autonomy_request = AutonomyRequest(sim, autonomy_mode=FullAutonomy, object_list=object_list, static_commodity_list=static_commodity_list, limited_autonomy_allowed=False, autonomy_mode_label_override='WeddingMakeGuestsWatch') selected_interaction = services.autonomy_service().find_best_action(autonomy_request) while selected_interaction is not None: if AffordanceObjectPair.execute_interaction(selected_interaction): self._guest_sim_infos_to_force_watch.remove(sim_info) if self._guest_sim_infos_to_force_watch: self._alarm_handle = alarms.add_alarm(self, create_time_span(minutes=self.MAKE_GUESTS_WATCH_ALARM_TIME), self._make_guests_watch)
def _run_interaction_gen(self, timeline): target_sim = self.get_participant(interactions.ParticipantType.TargetSim) logger.assert_log(target_sim is not None, 'target_sim is invalid in SocialPickerSuperInteraction._run_interaction_gen()', owner='rez') self.force_inertial = True context = self.context.clone_for_sim(self.sim, bucket=InteractionBucketType.BASED_ON_SOURCE) autonomy_request = AutonomyRequest(self.sim, autonomy_mode=autonomy.autonomy_modes.SocialAutonomy, static_commodity_list=[self.SOCIAL_STATIC_COMMODITY], object_list=[target_sim], context=context, push_super_on_prepare=True, consider_scores_of_zero=True) social_mixer = services.autonomy_service().find_best_action(autonomy_request) if social_mixer and not social_mixer.super_interaction.running: social_mixer.super_interaction = None for si in autonomy_request.interactions_to_invalidate: si.invalidate() autonomy_request.interactions_to_invalidate.clear() if social_mixer: return AffordanceObjectPair.execute_interaction(social_mixer) return event_testing.results.EnqueueResult.NONE
def _do_perform_gen(self, timeline): context = self.context.clone_for_continuation(self) max_priority = None aops_valid = [] invalid_aops_with_result = [] for (priority, aop) in self._aops_sorted_gen( self.target, context, super_interaction=self.super_interaction, **self.interaction_parameters): if max_priority is not None: if priority < max_priority: break test_result = aop.test(context) if test_result: aops_valid.append(aop) max_priority = priority else: invalid_aops_with_result.append((aop, test_result)) if not aops_valid: logger.error( 'Failed to find valid mixer affordance in AggregateMixerInteraction: {}, did we not run its test immediately before executing it?\n{}', self, invalid_aops_with_result, owner='rmccord') return ExecuteResult.NONE yield interactions_by_weight = [] for aop in aops_valid: interaction_result = aop.interaction_factory(context) if not interaction_result: raise RuntimeError( 'Failed to generate interaction from aop {}. {} [rmccord]'. format(aop, interaction_result)) interaction = interaction_result.interaction if len(aops_valid) == 1: weight = 0 else: weight = interaction.affordance.calculate_autonomy_weight( context.sim) interactions_by_weight.append((weight, interaction)) if not interactions_by_weight: return ExecuteResult.NONE yield (_, interaction) = max(interactions_by_weight, key=operator.itemgetter(0)) return AffordanceObjectPair.execute_interaction(interaction) yield
def _push_interaction(self, selected_interaction): if AffordanceObjectPair.execute_interaction(selected_interaction): if self.get_comfortable is not None: get_comfortable_liability = AutonomousGetComfortableLiability( self.owner) selected_interaction.add_liability( AutonomousGetComfortableLiability.LIABILITY_TOKEN, get_comfortable_liability) return True should_log = services.autonomy_service().should_log(self.owner) if should_log: logger.debug('Autonomy failed to push {}', selected_interaction.affordance) if selected_interaction.target: self.owner.add_lockout(selected_interaction.target, AutonomyMode.LOCKOUT_TIME) return False
def _on_starting_work(self): if self.preroll_autonomy is not None: chosen_interaction = self.preroll_autonomy().run_preroll(self.service_sim()) if chosen_interaction is None: self._had_preroll_work = False else: execute_result = AffordanceObjectPair.execute_interaction(chosen_interaction) if not execute_result: if self.fail_on_preroll_execute_failure: self._had_preroll_work = False if self.fake_perform_on_preroll_failure is not None: self._on_preroll_cancelled(chosen_interaction) elif self.fake_perform_on_preroll_failure is not None: chosen_interaction.register_on_cancelled_callback(self._on_preroll_cancelled) elif self.fake_perform_on_preroll_failure is not None: chosen_interaction.register_on_cancelled_callback(self._on_preroll_cancelled) if not self._had_preroll_work: self._change_state(LeaveSituationState(ServiceNpcEndWorkReason.NO_WORK_TO_DO))
def solve_motive(stat_type, opt_sim:OptionalTargetParam=None, _connection=None): sim = get_optional_target(opt_sim, _connection) if sim is None or stat_type is None: sims4.commands.output('Unable to identify Sim or Motive - invalid arguments.', _connection) return stat = sim.commodity_tracker.get_statistic(stat_type) if stat is None: sims4.commands.output('Unable to motive {} on the Sim .'.format(stat_type), _connection) return if not sim.queue.can_queue_visible_interaction(): sims4.commands.output('Interaction queue is full, cannot add anymore interactions.', _connection) return context = InteractionContext(sim, InteractionContext.SOURCE_AUTONOMY, priority.Priority.High, bucket=InteractionBucketType.DEFAULT) autonomy_request = autonomy.autonomy_request.AutonomyRequest(sim, autonomy_mode=autonomy.autonomy_modes.FullAutonomy, commodity_list=[stat], context=context, consider_scores_of_zero=True, posture_behavior=AutonomyPostureBehavior.IGNORE_SI_STATE, is_script_request=True, allow_opportunity_cost=False, autonomy_mode_label_override='AutoSolveMotive') selected_interaction = services.autonomy_service().find_best_action(autonomy_request) if selected_interaction is None: stat_str = '{}'.format(stat_type) commodity_interaction = CommodityTuning.BLADDER_SOLVING_FAILURE_INTERACTION if stat_str == "<class 'sims4.tuning.instances.motive_Energy'>": commodity_interaction = CommodityTuning.ENERGY_SOLVING_FAILURE_INTERACTION elif stat_str == "<class 'sims4.tuning.instances.motive_Fun'>": commodity_interaction = CommodityTuning.FUN_SOLVING_FAILURE_INTERACTION elif stat_str == "<class 'sims4.tuning.instances.motive_Hunger'>": commodity_interaction = CommodityTuning.HUNGER_SOLVING_FAILURE_INTERACTION elif stat_str == "<class 'sims4.tuning.instances.motive_Hygiene'>": commodity_interaction = CommodityTuning.HYGIENE_SOLVING_FAILURE_INTERACTION elif stat_str == "<class 'sims4.tuning.instances.motive_Social'>": commodity_interaction = CommodityTuning.SOCIAL_SOLVING_FAILURE_INTERACTION if not sim.queue.has_duplicate_super_affordance(commodity_interaction, sim, None): failure_aop = AffordanceObjectPair(commodity_interaction, None, commodity_interaction, None) failure_aop.test_and_execute(context) sims4.commands.output('Could not find a good interaction to solve {}.'.format(stat_type), _connection) return if sim.queue.has_duplicate_super_affordance(selected_interaction.affordance, sim, selected_interaction.target): sims4.commands.output('Duplicate Interaction in the queue.', _connection) return if not AffordanceObjectPair.execute_interaction(selected_interaction): sims4.commands.output('Failed to execute SI {}.'.format(selected_interaction), _connection) return sims4.commands.output('Successfully executed SI {}.'.format(selected_interaction), _connection)
def _on_starting_work(self): if self.preroll_autonomy is not None: chosen_interaction = self.preroll_autonomy().run_preroll( self.service_sim()) if chosen_interaction is None: self._had_preroll_work = False else: execute_result = AffordanceObjectPair.execute_interaction( chosen_interaction) if not execute_result: if self.fail_on_preroll_execute_failure: self._had_preroll_work = False if self.fake_perform_on_preroll_failure is not None: self._on_preroll_cancelled(chosen_interaction) elif self.fake_perform_on_preroll_failure is not None: chosen_interaction.register_on_cancelled_callback( self._on_preroll_cancelled) elif self.fake_perform_on_preroll_failure is not None: chosen_interaction.register_on_cancelled_callback( self._on_preroll_cancelled) if not self._had_preroll_work: self._change_state( LeaveSituationState(ServiceNpcEndWorkReason.NO_WORK_TO_DO))
def solve_motive( stat_type: TunableInstanceParam(sims4.resources.Types.STATISTIC, exact_match=True), opt_sim: OptionalTargetParam = None, _connection=None): sim = get_optional_target(opt_sim, _connection) if sim is None or stat_type is None: sims4.commands.output( 'Unable to identify Sim or Motive - invalid arguments.', _connection) return if sim.commodity_tracker is None: sims4.commands.output( 'Unable to solve motive - sim info has no commodity tracker.', _connection) return stat = sim.commodity_tracker.get_statistic(stat_type) if stat is None: sims4.commands.output( 'Unable to solve motive {} on the Sim .'.format(stat_type), _connection) return if not sim.queue.can_queue_visible_interaction(): sims4.commands.output( 'Interaction queue is full, cannot add anymore interactions.', _connection) return context = InteractionContext(sim, InteractionContext.SOURCE_AUTONOMY, priority.Priority.High, bucket=InteractionBucketType.DEFAULT) autonomy_request = autonomy.autonomy_request.AutonomyRequest( sim, autonomy_mode=autonomy.autonomy_modes.FullAutonomy, commodity_list=[stat], context=context, consider_scores_of_zero=True, posture_behavior=AutonomyPostureBehavior.IGNORE_SI_STATE, is_script_request=True, allow_opportunity_cost=False, autonomy_mode_label_override='AutoSolveMotive') selected_interaction = services.autonomy_service().find_best_action( autonomy_request) if selected_interaction is None: commodity_interaction = stat_type.commodity_autosolve_failure_interaction if commodity_interaction is None: return if not sim.queue.has_duplicate_super_affordance( commodity_interaction, sim, None): failure_aop = AffordanceObjectPair(commodity_interaction, None, commodity_interaction, None) failure_aop.test_and_execute(context) sims4.commands.output( 'Could not find a good interaction to solve {}.'.format(stat_type), _connection) return if sim.queue.has_duplicate_super_affordance( selected_interaction.affordance, sim, selected_interaction.target): sims4.commands.output('Duplicate Interaction in the queue.', _connection) return if not AffordanceObjectPair.execute_interaction(selected_interaction): sims4.commands.output( 'Failed to execute SI {}.'.format(selected_interaction), _connection) return sims4.commands.output( 'Successfully executed SI {}.'.format(selected_interaction), _connection)
def run_subaction_autonomy(self): if not SubActionAutonomy.test(self.owner): if gsi_handlers.autonomy_handlers.archiver.enabled: gsi_handlers.autonomy_handlers.archive_autonomy_data( self.owner, 'None - Autonomy Disabled', 'SubActionAutonomy', gsi_handlers.autonomy_handlers.EMPTY_ARCHIVE) return EnqueueResult.NONE attempt_to_use_cache = False if gsi_handlers.autonomy_handlers.archiver.enabled: caching_info = [] else: caching_info = None while self._cached_mixer_interactions: attempt_to_use_cache = True interaction_to_run = self._cached_mixer_interactions.pop(0) if self._should_run_cached_interaction(interaction_to_run): enqueue_result = AffordanceObjectPair.execute_interaction( interaction_to_run) if enqueue_result: if gsi_handlers.autonomy_handlers.archiver.enabled: gsi_handlers.autonomy_handlers.archive_autonomy_data( self.owner, 'Using Cache: {}'.format(interaction_to_run), 'SubActionAutonomy', gsi_handlers.autonomy_handlers.EMPTY_ARCHIVE) return enqueue_result if interaction_to_run: interaction_to_run.invalidate() while caching_info is not None: caching_info.append( 'Failed to use cache interaction: {}'.format( interaction_to_run)) continue if caching_info is not None and attempt_to_use_cache: caching_info.append('Cache invalid:Regenerating') self.invalidate_mixer_interaction_cache(None) context = InteractionContext(self.owner, InteractionSource.AUTONOMY, Priority.Low) autonomy_request = AutonomyRequest(self.owner, context=context, consider_scores_of_zero=True, autonomy_mode=SubActionAutonomy) if caching_info is not None: caching_info.append('Caching: Mixers - START') initial_probability_result = None while len(self._cached_mixer_interactions) < self.MIXERS_TO_CACHE: interaction = services.autonomy_service().find_best_action( autonomy_request, consider_all_options=True, archive_if_enabled=False) if interaction is None: break if caching_info is not None: caching_info.append( 'caching interaction: {}'.format(interaction)) if initial_probability_result is None: initial_probability_result = list( autonomy_request.gsi_data['Probability']) self._cached_mixer_interactions.append(interaction) if caching_info is not None: caching_info.append('Caching: Mixers - DONE') if self._cached_mixer_interactions: interaction = self._cached_mixer_interactions.pop(0) if caching_info is not None: caching_info.append('Executing mixer: {}'.format(interaction)) enqueue_result = AffordanceObjectPair.execute_interaction( interaction) if caching_info is not None: autonomy_request.gsi_data['caching_info'] = caching_info autonomy_request.gsi_data[ 'Probability'] = initial_probability_result if enqueue_result: result_info = str(interaction) else: result_info = 'None - failed to execute: {}'.format( interaction) gsi_handlers.autonomy_handlers.archive_autonomy_data( autonomy_request.sim, result_info, autonomy_request.autonomy_mode_label, autonomy_request.gsi_data) return enqueue_result return EnqueueResult.NONE
def activate(cls): tutorial_service = services.get_tutorial_service() client = services.client_manager().get_first_client() actor_sim_info = client.active_sim.sim_info target_sim_info = actor_sim_info housemate_sim_info = None tutorial_drama_node = None drama_scheduler = services.drama_scheduler_service() if drama_scheduler is not None: drama_nodes = drama_scheduler.get_running_nodes_by_drama_node_type( DramaNodeType.TUTORIAL) if drama_nodes: tutorial_drama_node = drama_nodes[0] housemate_sim_info = tutorial_drama_node.get_housemate_sim_info( ) player_sim_info = tutorial_drama_node.get_player_sim_info() if cls.sim_actor == TutorialTipActorOption.PLAYER_SIM: actor_sim_info = player_sim_info elif cls.sim_actor == TutorialTipActorOption.HOUSEMATE_SIM: actor_sim_info = housemate_sim_info if cls.sim_target == TutorialTipActorOption.PLAYER_SIM: target_sim_info = player_sim_info elif cls.sim_target == TutorialTipActorOption.HOUSEMATE_SIM: target_sim_info = housemate_sim_info if cls.gameplay_immediate_test is not None: resolver = event_testing.resolver.SingleSimResolver(actor_sim_info) if resolver(cls.gameplay_immediate_test): cls.satisfy() else: return for buff_ref in cls.buffs: actor_sim_info.add_buff_from_op(buff_ref.buff_type, buff_reason=buff_ref.buff_reason) if cls.gameplay_test is not None: services.get_event_manager().register_tests( cls, [cls.gameplay_test]) if cls.satisfy_on_active_sim_change: client = services.client_manager().get_first_client() if client is not None: client.register_active_sim_changed(cls._on_active_sim_change) if cls.commodities_to_solve: actor_sim = actor_sim_info.get_sim_instance() if actor_sim is not None: context = InteractionContext( actor_sim, InteractionContext.SOURCE_SCRIPT_WITH_USER_INTENT, priority.Priority.High, bucket=InteractionBucketType.DEFAULT) for commodity in cls.commodities_to_solve: if not actor_sim.queue.can_queue_visible_interaction(): break autonomy_request = autonomy.autonomy_request.AutonomyRequest( actor_sim, autonomy_mode=autonomy.autonomy_modes.FullAutonomy, commodity_list=(commodity, ), context=context, consider_scores_of_zero=True, posture_behavior=AutonomyPostureBehavior. IGNORE_SI_STATE, distance_estimation_behavior= AutonomyDistanceEstimationBehavior. ALLOW_UNREACHABLE_LOCATIONS, allow_opportunity_cost=False, autonomy_mode_label_override='Tutorial') selected_interaction = services.autonomy_service( ).find_best_action(autonomy_request) AffordanceObjectPair.execute_interaction( selected_interaction) if cls.gameplay_loots: resolver = DoubleSimResolver(actor_sim_info, target_sim_info) for loot_action in cls.gameplay_loots: loot_action.apply_to_resolver(resolver) if cls.restricted_affordances is not None and tutorial_service is not None: tutorial_service.set_restricted_affordances( cls.restricted_affordances.visible_affordances, cls.restricted_affordances.tooltip, cls.restricted_affordances.enabled_affordances) if cls.call_to_actions is not None: call_to_action_service = services.call_to_action_service() for call_to_action_fact in cls.call_to_actions: call_to_action_service.begin(call_to_action_fact, None) if cls.add_target_to_actor_household: household_manager = services.household_manager() household_manager.switch_sim_household(target_sim_info) if cls.make_housemate_unselectable and tutorial_service is not None: tutorial_service.set_unselectable_sim(housemate_sim_info) if cls.end_drama_node and tutorial_drama_node is not None: tutorial_drama_node.end() if cls.time_of_day is not None and tutorial_service is not None: tutorial_service.add_tutorial_alarm(cls, lambda _: cls.satisfy(), cls.time_of_day)
def run_subaction_autonomy(self): if not SubActionAutonomy.test(self.owner): if gsi_handlers.autonomy_handlers.archiver.enabled: gsi_handlers.autonomy_handlers.archive_autonomy_data( self.owner, 'None - Autonomy Disabled', 'SubActionAutonomy', gsi_handlers.autonomy_handlers.EMPTY_ARCHIVE) return EnqueueResult.NONE attempt_to_use_cache = False if gsi_handlers.autonomy_handlers.archiver.enabled: caching_info = [] else: caching_info = None sub_action_ping_data = None if autonomy.autonomy_util.info_start_time is not None: sub_action_ping_data = autonomy.autonomy_util.sim_id_to_sub_autonomy_ping.get( self.owner.id, None) while self._cached_mixer_interactions: attempt_to_use_cache = True interaction_to_run = self._cached_mixer_interactions.pop(0) if self._should_run_cached_interaction(interaction_to_run): enqueue_result = AffordanceObjectPair.execute_interaction( interaction_to_run) if enqueue_result: if gsi_handlers.autonomy_handlers.archiver.enabled: gsi_handlers.autonomy_handlers.archive_autonomy_data( self.owner, 'Using Cache: {}'.format(interaction_to_run), 'SubActionAutonomy', gsi_handlers.autonomy_handlers.EMPTY_ARCHIVE) if sub_action_ping_data is not None: sub_action_ping_data.cache_hits += 1 return enqueue_result if interaction_to_run: interaction_to_run.invalidate() if caching_info is not None: caching_info.append( 'Failed to use cache interaction: {}'.format( interaction_to_run)) if sub_action_ping_data is not None: sub_action_ping_data.cache_use_fails += 1 if caching_info is not None and attempt_to_use_cache: caching_info.append('Cache invalid:Regenerating') self.invalidate_mixer_interaction_cache(None) context = InteractionContext(self.owner, InteractionSource.AUTONOMY, Priority.Low) autonomy_request = AutonomyRequest(self.owner, context=context, consider_scores_of_zero=True, skipped_affordance_list=[], autonomy_mode=SubActionAutonomy) if caching_info is not None: caching_info.append('Caching: Mixers - START') mixers_to_cache = self._get_number_mixers_cache() initial_probability_result = None while len(self._cached_mixer_interactions) < mixers_to_cache: interaction = services.autonomy_service().find_best_action( autonomy_request, consider_all_options=True, archive_if_enabled=False) if interaction is None: break if caching_info is not None: caching_info.append( 'caching interaction: {}'.format(interaction)) if initial_probability_result is None: initial_probability_result = list( autonomy_request.gsi_data[GSIDataKeys.PROBABILITY_KEY]) self._cached_mixer_interactions.append(interaction) autonomy_request.skipped_affordance_list.clear() autonomy_request.skip_adding_request_record = True if interaction.lock_out_time is not None: if not interaction.lock_out_time.target_based_lock_out: autonomy_request.skipped_affordance_list.append( interaction.affordance) if caching_info is not None: caching_info.append('Caching: Mixers - DONE') if autonomy.autonomy_util.info_start_time is not None: if sub_action_ping_data is None: sub_action_ping_data = autonomy.autonomy_util.SubAutonomyPingData( ) sub_action_ping_data.num_mixers_cached.append( (len(self._cached_mixer_interactions), mixers_to_cache)) if self._cached_mixer_interactions: interaction = self._cached_mixer_interactions.pop(0) if caching_info is not None: caching_info.append('Executing mixer: {}'.format(interaction)) enqueue_result = AffordanceObjectPair.execute_interaction( interaction) if caching_info is not None: autonomy_request.gsi_data[ GSIDataKeys.MIXER_CACHING_INFO_KEY] = caching_info autonomy_request.gsi_data[ GSIDataKeys.PROBABILITY_KEY] = initial_probability_result if enqueue_result: result_info = str(interaction) else: result_info = 'None - failed to execute: {}'.format( interaction) gsi_handlers.autonomy_handlers.archive_autonomy_data( autonomy_request.sim, result_info, autonomy_request.autonomy_mode_label, autonomy_request.gsi_data) autonomy_request.gsi_data = None if sub_action_ping_data is not None: sub_action_ping_data.cache_hits += 1 autonomy.autonomy_util.sim_id_to_sub_autonomy_ping[ self.owner.id] = sub_action_ping_data return enqueue_result else: return EnqueueResult.NONE