def create_si(): drink_target = self.created_target target_affordance = drink_target.get_consume_affordance() context = InteractionContext(self.order_sim, self.source, self.priority, insert_strategy=QueueInsertStrategy.NEXT, group_id=self.group_id) context.carry_target = drink_target aop = AffordanceObjectPair(target_affordance, drink_target, target_affordance, None) return (aop, context)
def _create_and_establish_familiar_link(self): sim = self._owner.get_sim_instance(allow_hidden_flags=ALL_HIDDEN_REASONS_EXCEPT_UNINITIALIZED) if sim is None: return familiar_type = self._familiars[self._active_familiar_id].familiar_type familiar_data = FamiliarTracker.FAMILIAR_DATA[familiar_type] if familiar_data.familiar_type is None: try: self._active_familiar_obj_id = self._familiars[self._active_familiar_id].pet_familiar_id pet_familiar_sim_info = services.sim_info_manager().get(self._active_familiar_obj_id) buff_info_to_add = self.PET_FAMILIAR_BUFF[pet_familiar_sim_info.age][pet_familiar_sim_info.extended_species] self._pet_buff_handle = pet_familiar_sim_info.add_buff(buff_info_to_add.buff_type, buff_reason=buff_info_to_add.buff_reason) pet_familiar = services.object_manager().get(self._active_familiar_obj_id) if services.current_zone().is_zone_running: if pet_familiar is None: services.current_zone().venue_service.active_venue.summon_npcs((pet_familiar_sim_info,), NPCSummoningPurpose.BRING_PLAYER_SIM_TO_LOT) else: context = InteractionContext(pet_familiar, InteractionContext.SOURCE_SCRIPT, Priority.Critical, insert_strategy=QueueInsertStrategy.NEXT) pet_familiar.push_super_affordance(FamiliarTracker.PET_FAMILIAR_SET_ACTIVE_AFFORDANCE, None, context) except Exception as e: self._on_familiar_summon_failure('Exception encountered when trying to create familiar. Deactivating familiar.', familiar_object=pet_familiar, exc=e) if self._sim_buff_handle is None: self._sim_buff_handle = self._owner.add_buff(self.ACTIVE_FAMILIAR_BUFF.buff_type, buff_reason=self.ACTIVE_FAMILIAR_BUFF.buff_reason) return familiar = services.object_manager().get(self._active_familiar_obj_id) if familiar is None: try: familiar_obj_def = familiar_data.familiar_type.familiar_object familiar = create_object(familiar_obj_def) if familiar is None: self._on_familiar_summon_failure('Failure to create familiar object. Deactivating familiar.') return resolver = SingleSimResolver(self._owner) if not FamiliarTracker.FAMILIAR_PLACEMENT.try_place_object(familiar, resolver): self._on_familiar_summon_failure('Failure to create familiar object. Deactivating familiar.', familiar_object=familiar, warn=True) return self._active_familiar_obj_id = familiar.id except Exception as e: self._on_familiar_summon_failure('Exception encountered when trying to create familiar. Deactivating familiar.', familiar_object=familiar, exc=e) return context = InteractionContext(sim, InteractionSource.SCRIPT, Priority.Critical, insert_strategy=QueueInsertStrategy.NEXT) result = sim.push_super_affordance(familiar_data.familiar_type.follow_affordance, familiar, context) if not result: self._on_familiar_summon_failure('Failed to push familiar follow interaction. Deactivating Familiar.', familiar_object=familiar) return result.interaction.register_on_finishing_callback(self._on_familiar_follow_interaction_finished_prematurely) if self._sim_buff_handle is None: self._sim_buff_handle = self._owner.add_buff(self.ACTIVE_FAMILIAR_BUFF.buff_type, buff_reason=self.ACTIVE_FAMILIAR_BUFF.buff_reason)
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 push_walk_affordance(self, alarm_handle): sim = self.owner.get_walker() if sim.has_any_interaction_running_or_queued_of_types( (self.attractor_node_affordance, )): return for (_, carry_posture, carry_target) in get_carried_objects_gen(sim): if carry_target.transient: if carry_posture.source_interaction.running: break else: return self._cancel_alarm(WalkState.RETRY_ALARM_NAME) self._attempts += 1 if self._attempts > self.max_attempts: self.owner.walk_onward() return context = InteractionContext(sim, InteractionContext.SOURCE_SCRIPT, Priority.High, run_priority=Priority.Low, insert_strategy=QueueInsertStrategy.NEXT) walk_aop = interactions.aop.AffordanceObjectPair( self.attractor_node_affordance, self._attractor_point, self.attractor_node_affordance, None) test_result = walk_aop.test(context) if test_result: execute_result = walk_aop.execute(context) if execute_result: self._walk_interaction = execute_result[1] self._create_or_load_alarm(WalkState.RETRY_ALARM_NAME, self.time_between_attempts, self.push_walk_affordance, repeating=True)
def build_msg(self, **kwargs): message = super().build_msg(**kwargs) message.dialog_type = Dialog_pb2.UiDialogMessage.MULTI_PICKER if self.text_input is not None: text_input_overrides = {} (text_name, text) = self.existing_text text_input_overrides = {} if text: text_input_overrides[text_name] = lambda *_, **__: LocalizationHelperTuning.get_raw_text(text) self.text_input.build_msg(self, message, name=text_name, text_input_overrides=text_input_overrides if text_input_overrides else None) context = InteractionContext(self._owner(), InteractionSource.SCRIPT, Priority.Low) multi_picker_msg = Dialog_pb2.UiDialogMultiPicker() for picker_data in self.pickers: aop = AffordanceObjectPair(picker_data.picker_interaction, None, picker_data.picker_interaction, None) result = aop.interaction_factory(context) if not result: continue interaction = result.interaction picker_tuning = picker_data.picker_interaction.picker_dialog if picker_tuning.title is None: title = lambda *_, **__: interaction.get_name(apply_name_modifiers=False) else: title = self.picker_dialog.title dialog = picker_tuning(self._owner(), title=title, resolver=interaction.get_resolver(context=context)) interaction._setup_dialog(dialog) dialog.add_listener(interaction._on_picker_selected) self._picker_dialogs[dialog.dialog_id] = dialog new_message = dialog.build_msg() multi_picker_item = multi_picker_msg.multi_picker_items.add() multi_picker_item.picker_data = new_message.picker_data multi_picker_item.picker_id = new_message.dialog_id multi_picker_item.disabled_tooltip = picker_data.disabled_tooltip message.multi_picker_data = multi_picker_msg return message
def _test_execute_buy_affordance(self, object_to_buy): retail_component = object_to_buy.retail_component if retail_component is None: return (object_to_buy, TestResult(False, '{} missing retail component')) buy_affordance = retail_component.get_buy_affordance() if buy_affordance is None: return (object_to_buy, TestResult(False, '{} missing buy affordance')) context = InteractionContext( self.owner._customer, InteractionContext.SOURCE_SCRIPT, Priority.High, client=services.client_manager().get_first_client()) buy_aop = interactions.aop.AffordanceObjectPair( buy_affordance, object_to_buy, buy_affordance, None) test_result = buy_aop.test(context) execute_result = None if test_result: execute_result = buy_aop.execute(context) if execute_result: for custom_key in self.owner.buy_interaction.custom_keys_gen(): self._test_event_register(TestEvent.InteractionComplete, custom_key) self.object_id = object_to_buy.id return (object_to_buy, EnqueueResult(test_result, execute_result))
def find_target_and_push_interaction(self): if self.targets is None: self.owner._self_destruct() return for obj in sorted(self.targets, key=operator.attrgetter('part_group_index')): if self._previous_si is not None: context = self._previous_si.context.clone_for_continuation( self._previous_si) else: initiating_sim = self.owner.initiating_sim_info.get_sim_instance( ) context = InteractionContext( initiating_sim, InteractionContext.SOURCE_SCRIPT, Priority.High, insert_strategy=QueueInsertStrategy.FIRST) resolver = self.interaction.get_resolver(target=obj, context=context) if not self.owner.tests.run_tests(resolver): self.targets.remove(obj) else: self.targets.remove(obj) self._target = obj return self.push_interaction(context=context) return False
def handle_late_violator(self, sim): self._cancel_unavailable_interactions((sim, )) self.add_override_for_sim(sim) liabilities = ((LATE_SHOO_LIABILITY, LateShooLiability(self, sim)), ) result = self._route_sim_away(sim, liabilities=liabilities) if not result: return if not self._violators: context = InteractionContext( sim, InteractionContext.SOURCE_SCRIPT, Priority.High, insert_strategy=QueueInsertStrategy.NEXT) result = sim.push_super_affordance( self._EMBARRASSED_AFFORDANCE, self.interaction.get_participant(ParticipantType.Actor), context) if not result: logger.error( 'Failed to push the embarrassed affordance on Sim {}. Interaction {}. Result {}. Context {} ', sim, self.interaction, result, context, owner='tastle') return self._late_violators.add(sim)
def run_age_up(kid): def age_up_exit_behavior(): new_bassinet = create_object( Baby.get_corresponding_definition( middle_bassinet.definition)) new_bassinet.location = middle_bassinet.location middle_bassinet.make_transient() kid.fade_opacity(1, 0) kid.visibility = VisibilityState(False) affordance = Baby.BABY_AGE_UP.age_up_affordance aop = AffordanceObjectPair( affordance, middle_bassinet, affordance, None, exit_functions=(age_up_exit_behavior, )) context = InteractionContext( kid, InteractionSource.SCRIPT, interactions.priority.Priority.Critical, insert_strategy=QueueInsertStrategy.NEXT) result = aop.test_and_execute(context) if result: result.interaction.add_liability( AGING_LIABILITY, AgingLiability(sim_info, Age.BABY)) else: logger.error('Failed to run baby age up interaction.', owner='jjacobson') return True
def run_preroll(self, sim): autonomy_service = services.autonomy_service() context = InteractionContext(sim, self.preroll_source, self.preroll_priority, client=None, pick=None) autonomy_distance_estimation_behavior = AutonomyDistanceEstimationBehavior.ALLOW_UNREACHABLE_LOCATIONS if self.allow_unreachable_destinations else AutonomyDistanceEstimationBehavior.FULL autonomy_request = AutonomyRequest( sim, autonomy_mode=FullAutonomy, skipped_static_commodities=AutonomyComponent. STANDARD_STATIC_COMMODITY_SKIP_SET, limited_autonomy_allowed=False, context=context, distance_estimation_behavior=autonomy_distance_estimation_behavior, autonomy_mode_label_override='NPCPrerollAutonomy') scored_interactions = autonomy_service.score_all_interactions( autonomy_request) compatible_scored_interactions = tuple([ scored_interaction_data for scored_interaction_data in scored_interactions if self.super_affordance_compatibility( scored_interaction_data.interaction.affordance) ]) chosen_interaction = autonomy_service.choose_best_interaction( compatible_scored_interactions, autonomy_request) autonomy_request.invalidate_created_interactions( excluded_si=chosen_interaction) return chosen_interaction
def get_name(cls, inst, target=None, context=None, **interaction_parameters): if context is None: if inst is not None: context = InteractionContext(inst.sim, InteractionContext.SOURCE_SCRIPT, Priority.High) if context is not None and context.sim is not None: career = context.sim.sim_info.career_tracker.career_currently_within_hours if career is not None: career_interaction = career.career_rabbit_hole.get_affordance( context.sim.sim_info, career.guid64) if career_interaction is None: career_interaction = career.career_rabbit_hole.get_travel_affordance( context.sim.sim_info, career.guid64) name = career_interaction.get_name(target=target, context=context, **interaction_parameters) if name is not None: return name logger.error( 'Failed to get rabbit hole travel display name for rabbit hole: {}', cls) return super(CareerProxyInteractionMixin, cls).get_name(cls, inst, target=target, context=context, **interaction_parameters)
def __call__(self, role_state, role_affordance_target, situation=None): sim = role_state.sim context = InteractionContext(sim, self.source, self.priority, run_priority=self.run_priority, bucket=InteractionBucketType.DEFAULT) autonomy_request = autonomy.autonomy_request.AutonomyRequest( sim, FullAutonomy, commodity_list=self.commodities, static_commodity_list=self.static_commodities, apply_opportunity_cost=False, is_script_request=True, context=context, si_state_view=sim.si_state, limited_autonomy_allowed=True, radius_to_consider=self.radius_to_consider, consider_scores_of_zero=self.consider_scores_of_zero, autonomy_mode_label_override='ParameterizedAutonomy', off_lot_autonomy_rule_override=self.off_lot_rule, test_connectivity_to_target_object=self. test_connectivity_to_target, reping_delay_on_fail=self.full_ping_on_fail() if self.full_ping_on_fail is not None else None) sim.queue_autonomy_request(autonomy_request) sim.run_full_autonomy_next_ping()
def _fixup_sims_outfit(self, sim): sim_info = sim.sim_info if sim_info.is_child_or_younger: return leader_sim_info = self.requesting_sim_info if sim_info.species != leader_sim_info.species or sim_info.clothing_preference_gender != leader_sim_info.clothing_preference_gender: return leader_current_outfit = leader_sim_info.get_current_outfit() if leader_current_outfit[0] == OutfitCategory.BATHING: leader_current_outfit = (OutfitCategory.EVERYDAY, 0) with leader_sim_info.set_temporary_outfit_flags( leader_current_outfit[0], leader_current_outfit[1], BodyTypeFlag.CLOTHING_ALL): sim_info.generate_merged_outfit(leader_sim_info, (OutfitCategory.SITUATION, 0), sim_info.get_current_outfit(), leader_current_outfit, preserve_outfit_flags=True) if self.manager.sim_being_created is sim or not services.current_zone( ).is_zone_running: sim.set_current_outfit((OutfitCategory.SITUATION, 0)) else: context = InteractionContext( sim, InteractionContext.SOURCE_SCRIPT, interactions.priority.Priority.High, insert_strategy=QueueInsertStrategy.NEXT, bucket=interactions.context.InteractionBucketType.DEFAULT) sim.push_super_affordance(self.CHANGE_TO_SITUATION_OUTFIT, None, context)
def on_activate(self, reader=None): super().on_activate(reader) leader_sim = self.owner.initiating_sim_info.get_sim_instance() if leader_sim is None: self.owner._self_destruct() members = list(self.owner.all_sims_in_situation_gen()) constraint_affordance = self.owner.constraint_affordance follower_sim_ids = set() for sim in members: if sim is leader_sim: if not sim.si_state.is_running_affordance( self.owner.constraint_leader_affordance): self.owner.remove_sim_from_situation(sim) if not sim.si_state.is_running_affordance( constraint_affordance): self.owner.remove_sim_from_situation(sim) else: follower_sim_ids.add(sim.id) elif not sim.si_state.is_running_affordance(constraint_affordance): self.owner.remove_sim_from_situation(sim) else: follower_sim_ids.add(sim.id) interaction_context = InteractionContext( leader_sim, InteractionSource.SCRIPT_WITH_USER_INTENT, Priority.High) aop = AffordanceObjectPair(self.owner.affordance, self.owner._target_object, self.owner.affordance, None, picked_item_ids=follower_sim_ids) aop.test_and_execute(interaction_context)
def _on_spawn(sim): affordance = bassinet.get_age_up_addordance() aop = AffordanceObjectPair(affordance, middle_bassinet, affordance, None, is_baby_age_up=True) context = InteractionContext(sim, InteractionSource.SCRIPT, Priority.Critical, insert_strategy=QueueInsertStrategy.NEXT) result = aop.test_and_execute(context) if not result: logger.error('Failed to run baby age up interaction: {}', result, owner='jjacobson')
def handle_special_case_sims(self): for (sim, affordance) in self.special_case_sims.items(): already_pushed = False canceling_interactions = set() for si in sim.get_all_running_and_queued_interactions(): if si.affordance.provided_posture_type is not None: continue if si.affordance.interaction_category_tags & self.species_interaction_speed_requirements.speed_affordance_tags: already_pushed = True else: canceling_interactions.add(si) for si in canceling_interactions: si.cancel(FinishingType.LIABILITY, cancel_reason_msg='Super speed 3 SI cancelation.') if already_pushed: for buff in self.GLOBAL_EXEMPT_SIM_BUFFS: if not sim.sim_info.has_buff(buff.buff_type): sim.sim_info.add_buff(buff.buff_type) else: context = InteractionContext( sim, InteractionContext.SOURCE_SCRIPT, Priority.High, insert_strategy=QueueInsertStrategy.NEXT) sim.push_super_affordance(affordance, sim, context) for buff in self.species_interaction_speed_requirements.exempt_sim_buffs: sim.sim_info.add_buff(buff.buff_type) for buff in self.GLOBAL_EXEMPT_SIM_BUFFS: sim.sim_info.add_buff(buff.buff_type)
def on_remove(self): super().on_remove() sim = self._betrothed_sims[0] target = self._betrothed_sims[1] if self.should_push_move_in and sim is not None and target is not None: priority = Priority.High context = InteractionContext(sim, InteractionContext.SOURCE_SCRIPT, priority) sim.push_super_affordance(self.move_in_together_interaction, target, context)
def _push_interaction(self): sim = self.owner._leaver interaction_context = InteractionContext(sim, InteractionContext.SOURCE_SCRIPT, Priority.Critical) enqueue_result = sim.push_super_affordance(self.owner.affordance_to_push, None, interaction_context) if not enqueue_result or enqueue_result.interaction.is_finishing: logger.debug('Leaver :{} failed to push leave interaction', self.owner._leaver) return logger.debug('Leaver :{} pushed leave interaction', sim)
def send_active_household_toddlers_home(self): active_household = services.active_household() if active_household is None: return instanced_toddlers = [sim for sim in active_household.instanced_sims_gen() if sim.sim_info.is_toddler] for toddler in instanced_toddlers: interaction_context = InteractionContext(toddler, InteractionContext.SOURCE_SCRIPT, Priority.Critical) toddler.push_super_affordance(TravelTuning.GO_HOME_INTERACTION, None, interaction_context)
def _interrogation_statistic_callback(self, stat_type, old_value, new_value): if self.interrogation_statistic is not stat_type: return op = self._get_interrogation_op(InterrogationUpdateType.TYPE_UPDATE) Distributor.instance().add_op(self._initiating_sim, op) if self._initiating_sim is not None and self._target_sim is not None and self.interrogation_end_interaction_data.interrogation_statistic_threshold.compare(new_value): context = InteractionContext(self._initiating_sim, InteractionContext.SOURCE_SCRIPT, Priority.High) self._initiating_sim.push_super_affordance(self.interrogation_end_interaction_data.interrogation_end_interaction, self._target_sim, context)
def _push_get_comfortable_interaction(_): self._get_comfortable_alarm_handle = None if any(si.is_guaranteed() for si in self.owner.si_state): return context = InteractionContext(self.owner, InteractionSource.AUTONOMY, Priority.Low) self.owner.push_super_affordance(self.get_comfortable.affordance, None, context)
def on_activate(self, reader=None): super().on_activate(reader) if not services.get_door_service().has_front_door(): return for sim in self.owner.all_sims_in_situation_gen(): if sim.is_selectable: continue context = InteractionContext(sim, InteractionContext.SOURCE_SCRIPT, Priority.High, insert_strategy=QueueInsertStrategy.NEXT) sim.push_super_affordance(self._interaction_to_push, sim, context)
def _push_drink_pick_up(self): if self.order_sim is None: return if self.sim is self.order_sim and (self.process.orders or not self.should_push_consume(check_phase=False)): return drink_target = self.created_target context = InteractionContext(self.order_sim, self.source, self.priority, insert_strategy=QueueInsertStrategy.NEXT) affordance = drink_target.get_consume_affordance() self.order_sim.push_super_affordance(affordance, drink_target, context)
def run_employee_interaction(self, affordance, target_sim): active_sim = services.get_active_sim() if active_sim is None: return False context = InteractionContext(active_sim, InteractionContext.SOURCE_PIE_MENU, Priority.High) return active_sim.push_super_affordance( affordance, None, context, picked_item_ids=(target_sim.sim_id, ))
def push_interaction_on_all_sims(affordance, opt_target:RequiredTargetParam=None, _connection=None): target = opt_target.get_target() if opt_target is not None else None client = services.client_manager().get(_connection) for sim_info in client.selectable_sims: sim = sim_info.get_sim_instance() while sim is not None: context = InteractionContext(sim, InteractionContext.SOURCE_PIE_MENU, Priority.High, client=client, pick=None) sim.push_super_affordance(affordance, target, context) return True
def _on_set_sim_role_state(self, sim, job_type, role_state_type, role_affordance_target): super()._on_set_sim_role_state(sim, job_type, role_state_type, role_affordance_target) toddler = services.get_fire_service().get_toddler_to_save_for_sim(sim.sim_info) if toddler is None: self._change_state(_PanicState()) InteractionCancelCompatibility.cancel_interactions_for_reason(sim, InteractionCancelReason.DEATH, FinishingType.FIRE, 'Interaction was canceled due to saving a toddler from a fire.', additional_cancel_sources=(InteractionSource.SCRIPT,)) InteractionCancelCompatibility.cancel_interactions_for_reason(toddler, InteractionCancelReason.DEATH, FinishingType.FIRE, 'Interaction was canceled due to a toddler being saved from a fire.', additional_cancel_sources=(InteractionSource.SCRIPT,)) context = InteractionContext(sim, InteractionContext.SOURCE_SCRIPT, Priority.High, client=None, pick=None) sim.push_super_affordance(self.owner.save_toddler_interaction, toddler, context)
def _run_interaction_gen(self, timeline): main_group = self.sim.get_visible_group() if self._push_social is not None and main_group is None: context = InteractionContext(self.sim, InteractionContext.SOURCE_SCRIPT, self.context.priority) self.sim.push_super_affordance(self._push_social, self._from_rally_interaction.sim, context) yield from super()._run_interaction_gen(timeline)
def on_activate(self, reader=None): super().on_activate(reader) if self.owner._neighbor_sim is not None: context = InteractionContext( self.owner._neighbor_sim, InteractionContext.SOURCE_SCRIPT, Priority.High, insert_strategy=QueueInsertStrategy.NEXT) self.owner._neighbor_sim.push_super_affordance( self._interaction_to_push, self.owner._neighbor_sim, context)
def _push_run_away_affordance(self, pet_sim): if pet_sim is None or self.RUN_AWAY_INTERACTION is None: return EnqueueResult.NONE if not pet_sim.queue.can_queue_visible_interaction(): return EnqueueResult.NONE if pet_sim.queue.has_duplicate_super_affordance(self.RUN_AWAY_INTERACTION, pet_sim, pet_sim): return EnqueueResult.NONE context = InteractionContext(pet_sim, InteractionContext.SOURCE_SCRIPT, Priority.High, insert_strategy=QueueInsertStrategy.LAST) result = pet_sim.push_super_affordance(self.RUN_AWAY_INTERACTION, pet_sim, context) return result
def create_route_interaction(self): if self.owner.is_sim: aop = AffordanceObjectPair(AnimationInteraction, None, AnimationInteraction, None, hide_unrelated_held_props=False) context = InteractionContext(self.owner, InteractionContext.SOURCE_SCRIPT, Priority.High) self._route_interaction = aop.interaction_factory(context).interaction else: self._animation_context = AnimationContext() self._animation_context.add_ref(self._current_path) for slave_data in self.get_routing_slave_data(): slave_data.slave.routing_component.create_route_interaction()