def switch_sim_from_household_to_target_household(self, sim_info, starting_household, destination_household, destroy_if_empty_household=True): active_household = services.active_household() if services.hidden_sim_service().is_hidden(sim_info.id): services.hidden_sim_service().unhide(sim_info.id) if starting_household is destination_household: logger.error('Trying to run AddToHousehold basic extra on a sim who is already in the destination household.') return False if not destination_household.can_add_sim_info(sim_info): logger.error('Trying to run AddToHousehold basic extra when there is no room in the destination household.') return False starting_household.remove_sim_info(sim_info, destroy_if_empty_household=destroy_if_empty_household, assign_to_none=False) destination_household.add_sim_info_to_household(sim_info) client = services.client_manager().get_first_client() if destination_household is active_household: client.add_selectable_sim_info(sim_info) sim_info.apply_fixup_actions(SimInfoFixupActionTiming.ON_ADDED_TO_ACTIVE_HOUSEHOLD) else: client.remove_selectable_sim_info(sim_info) if sim_info.career_tracker is not None: sim_info.career_tracker.remove_invalid_careers() sim = sim_info.get_sim_instance() if sim is not None: sim.update_intended_position_on_active_lot(update_ui=True) situation_manager = services.get_zone_situation_manager() for situation in situation_manager.get_situations_sim_is_in(sim): if destination_household is active_household and situation.is_user_facing: continue situation_manager.remove_sim_from_situation(sim, situation.id) services.daycare_service().on_sim_spawn(sim_info) return True
def _run_interaction_gen(self, timeline): household = self._sim_info.household sim_infos_to_bring = services.daycare_service().get_abandoned_toddlers(household, (self._sim_info,)) sim_infos_to_bring.append(self._sim_info) caretaker_zone_ids = set() offlot_pets = set() current_zone_id = services.current_zone_id() for sim_info in household: if sim_info is self._sim_info: continue if sim_info.is_human: if sim_info.is_child_or_older: caretaker_zone_ids.add(sim_info.zone_id) if sim_info.zone_id == current_zone_id: continue if sim_info.zone_id == sim_info.vacation_or_home_zone_id: continue offlot_pets.add(sim_info) else: if sim_info.zone_id == current_zone_id: continue if sim_info.zone_id == sim_info.vacation_or_home_zone_id: continue offlot_pets.add(sim_info) for pet in offlot_pets: if pet.zone_id not in caretaker_zone_ids: sim_infos_to_bring.append(pet) daycare_service = services.daycare_service() if daycare_service.is_sim_info_at_daycare(self._sim_info): daycare_service.remove_sim_info_from_daycare(self._sim_info) services.current_zone().venue_service.active_venue.summon_npcs(tuple(sim_infos_to_bring), NPCSummoningPurpose.BRING_PLAYER_SIM_TO_LOT)
def _finalize_death(self): if self._has_finalized_death: return self._has_finalized_death = True sim_info = self.sim.sim_info current_household = sim_info.household death_object = self._death_object_data[0] if death_object is not None: death_object.add_dynamic_component(types.STORED_SIM_INFO_COMPONENT, sim_id=sim_info.id) death_object.update_object_tooltip() active_household = services.active_household() death_object.set_household_owner_id(active_household.id) if self._death_object_data[1]: try: if not build_buy.move_object_to_household_inventory( death_object): logger.error( 'Failed to place an urnstone for {} in household inventory: {}', sim_info, sim_info.household.id) except KeyError: logger.exception( 'Failed to place an urnstone for {} in household inventory: {}', sim_info, sim_info.household.id) death_tracker = sim_info.death_tracker death_type = None if self.death_info is not None: death_type = self.death_info.death_type death_tracker.set_death_type(death_type) if self.death_info is None or self.death_info.set_to_minimum_lod: sim_info.request_lod(SimInfoLODLevel.MINIMUM) if self._client is not None: self._client.set_next_sim_or_none( only_if_this_active_sim_info=sim_info) self._client.selectable_sims.remove_selectable_sim_info(sim_info) kill_all_fires = False if any(sim.can_live_alone for sim in self._client.selectable_sims): if self._show_off_lot_death_notification(): kill_all_fires = True else: kill_all_fires = True self._disband_travel_group() self._show_death_dialog() self._client.clear_selectable_sims() if kill_all_fires: fire_service = services.get_fire_service() if fire_service is not None: fire_service.kill() current_household.handle_adultless_household() services.daycare_service().refresh_household_daycare_nanny_status( sim_info)
def _complete_pregnancy_gen(self, timeline, pregnancy_tracker): is_off_lot_birth = False baby_sim_infos = [] for offspring_data in pregnancy_tracker.get_offspring_data_gen(): sim_info = pregnancy_tracker.create_sim_info(offspring_data) current_zone = services.current_zone() if current_zone.id == sim_info.zone_id: services.daycare_service().exclude_sim_from_daycare(sim_info) if not assign_bassinet_for_baby(sim_info): create_and_place_baby(sim_info) else: is_off_lot_birth = True baby_sim_infos.append(sim_info) offspring_count = pregnancy_tracker.offspring_count pregnancy_tracker.complete_pregnancy() self._apply_inherited_loots(baby_sim_infos, pregnancy_tracker) if is_off_lot_birth: travel_liability = TravelSimLiability( self, self.sim.sim_info, self.sim.sim_info.household.home_zone_id, expecting_dialog_response=True) self.add_liability(TRAVEL_SIM_LIABILITY, travel_liability) def on_travel_dialog_response(dialog): if dialog.accepted: if self.outcome is not None: loot = LootOperationList(self.get_resolver(), self.outcome.get_loot_list()) loot.apply_operations() save_lock_liability = self.get_liability( SaveLockLiability.LIABILITY_TOKEN) if save_lock_liability is not None: save_lock_liability.release() travel_liability.travel_dialog_response(dialog) travel_dialog_element = UiDialogElement( self.sim, self.get_resolver(), dialog=self.off_lot_birth_dialog, on_response=on_travel_dialog_response, additional_tokens=(offspring_count, )) result = yield from element_utils.run_child( timeline, travel_dialog_element) return result yield return True yield
def _get_selector_visual_type(self, sim_info): if sim_info.is_baby: return (Sims_pb2.SimPB.BABY, None) if sim_info.is_toddler and services.daycare_service( ).is_sim_info_at_daycare(sim_info): return (Sims_pb2.SimPB.AT_DAYCARE, None) if sim_info.household.missing_pet_tracker.is_pet_missing(sim_info): return (Sims_pb2.SimPB.PET_MISSING, None) sim = sim_info.get_sim_instance(allow_hidden_flags=ALL_HIDDEN_REASONS) for career in sim_info.careers.values(): if career.currently_at_work: if career.is_at_active_event and sim is None: return (Sims_pb2.SimPB.MISSING_ACTIVE_WORK, career.career_category) return (Sims_pb2.SimPB.AT_WORK, career.career_category) if career.is_late: if not career.taking_day_off: return (Sims_pb2.SimPB.LATE_FOR_WORK, career.career_category) if services.get_rabbit_hole_service( ).should_override_selector_visual_type(sim_info.id): return (Sims_pb2.SimPB.OTHER, None) if sim is not None and sim.has_hidden_flags( HiddenReasonFlag.RABBIT_HOLE): return (Sims_pb2.SimPB.OTHER, None) if services.hidden_sim_service().is_hidden(sim_info.id): return (Sims_pb2.SimPB.OTHER, None) tutorial_service = services.get_tutorial_service() if tutorial_service is not None and tutorial_service.is_sim_unselectable( sim_info): return (Sims_pb2.SimPB.OTHER, None) return (Sims_pb2.SimPB.NORMAL, None)
def release(self): super().release() daycare_service = services.daycare_service() for sim_info in self._sim_infos: if daycare_service is not None: daycare_service.set_sim_globally_available(sim_info) daycare_service.set_sim_available(sim_info)
def on_run(self): super().on_run() daycare_service = services.daycare_service() for sim_info in self._sim_infos: if daycare_service is not None: daycare_service.set_sim_globally_unavailable(sim_info) daycare_service.set_sim_unavailable(sim_info)
def _test(cls, *args, sim_info=None, **kwargs): if sim_info.zone_id == 0: return TestResult(False, 'Cannot travel to a zone of 0.') if sim_info.zone_id == services.current_zone_id(): return TestResult(False, 'Cannot switch to zone that is the current zone.') if sim_info in services.daycare_service().get_sim_infos_for_nanny(sim_info.household): return TestResult(False, 'Cannot switch to a sim that should be with the nanny.') return super()._test(*args, **kwargs)
def on_loading_screen_animation_finished(self): for sim_info in self.objects: sim_info.on_loading_screen_animation_finished() daycare_service = services.daycare_service() if daycare_service is not None: daycare_service.on_loading_screen_animation_finished() self._sims_traveled_to_zone.clear() self._sim_infos_saved_in_open_street.clear() self._sim_infos_saved_in_plex_group.clear() self._sim_infos_saved_in_zone.clear() self._sim_ids_to_skip_preroll.clear() self._sim_infos_injected_into_zone.clear() self._sim_info_to_spin_up_action = None self._firemeter = SimInfoFireMeter()
def _name_and_create_adoptee_gen(self, timeline): adopted_sim_info = self.get_participant(ParticipantType.PickedSim) if adopted_sim_info is None: return False yield last_name = SimSpawner.get_last_name(self.sim.last_name, adopted_sim_info.gender, adopted_sim_info.species) result = yield from self._do_renames_gen( timeline, (adopted_sim_info, ), additional_tokens=(last_name, )) if not result: return result yield parent_a = self.sim.sim_info parent_b = services.sim_info_manager().get(parent_a.spouse_sim_id) adoption_service = services.get_adoption_service() adoption_service.remove_sim_info(adopted_sim_info) (adopted_sim_info, _) = adoption_service.create_adoption_sim_info( adopted_sim_info, household=parent_a.household, account=parent_a.account, zone_id=parent_a.household.home_zone_id) PregnancyTracker.initialize_sim_info(adopted_sim_info, parent_a, parent_b) self.interaction_parameters['picked_item_ids'] = { adopted_sim_info.sim_id } services.daycare_service().exclude_sim_from_daycare(adopted_sim_info) if adopted_sim_info.age == Age.BABY: adopted_sim_info.set_zone_on_spawn() if not assign_bassinet_for_baby(adopted_sim_info): create_and_place_baby(adopted_sim_info) else: SimSpawner.spawn_sim(adopted_sim_info, sim_position=self.sim.position) return True yield
def _update_caregiver_status(self): care_dependent = self._guest_list.host_sim if care_dependent is None: return if care_dependent.household is None: return if care_dependent.is_being_destroyed: return available_sims = tuple( sim_info for sim_info in services.daycare_service().get_available_sims_gen()) current_caregivers = set(self._situation_sims) for sim in current_caregivers: self._pending_caregivers.discard(sim) eligible_caregivers = set( sim_info for sim_info in available_sims if self._is_valid_caregiver(care_dependent, sim_info)) if not eligible_caregivers: eligible_caregivers = set( sim_info for sim_info in care_dependent.household.can_live_alone_info_gen() if sim_info in available_sims) for sim in self._pending_caregivers: eligible_caregivers.discard(sim.sim_info) for potential_caregiver in tuple(eligible_caregivers): sim = potential_caregiver.get_sim_instance( allow_hidden_flags=ALL_HIDDEN_REASONS) if sim is None or sim.is_being_destroyed: eligible_caregivers.discard(potential_caregiver) else: if sim in current_caregivers: continue self.invite_sim_to_job(sim, job=self.caregiver_data.caregiver_job) self._pending_caregivers.add(sim) care_dependent.relationship_tracker.add_relationship_bit( potential_caregiver.sim_id, self.caregiver_data.care_dependent_bit) potential_caregiver.relationship_tracker.add_relationship_bit( care_dependent.sim_id, self.caregiver_data.caregiver_bit) for sim in tuple(current_caregivers): if sim.sim_info not in eligible_caregivers: self._remove_caregiver_rel_bits(care_dependent, sim.sim_info) self.remove_sim_from_situation(sim) current_caregivers.discard(sim)
def _is_valid_caregiver(self, care_dependent, caregiver, ignore_zone=False): if not ignore_zone and care_dependent.zone_id != caregiver.zone_id: return False if caregiver.is_toddler_or_younger: return False if caregiver.is_pet: return False if care_dependent.household_id == caregiver.household_id and any( caregiver.relationship_tracker.has_bit(care_dependent.sim_id, rel_bit) for rel_bit in self.caregiver_relationships): return True else: daycare_service = services.daycare_service() if daycare_service is not None and daycare_service.is_daycare_service_npc_available( sim_info=caregiver, household=care_dependent.household): return True return False
def move_sim_to_household(sim_info: SimInfo, household_id: int = None, destroy_if_empty_household: bool = True) -> bool: """move_sim_to_household(sim_info, household_id=None, destroy_if_empty_household=True) Move a Sim to the specified household or a new household if no Household is specified. :param sim_info: The Sim to add. :type sim_info: SimInfo :param household_id: The identifier of the Household to add the Sim to. :type household_id: int :param destroy_if_empty_household: If True, if the Sim comes from a household containing only them, then it will be destroyed after they are moved. :type destroy_if_empty_household: bool, optional :return: True, if the Sim was added to the Household successfully. False, if not. :rtype: bool """ active_household = services.active_household() starting_household = sim_info.household log.format_info('Moving a Sim to a new household.', sim=CommonSimNameUtils.get_full_name(sim_info), household_id=household_id, starting_household=starting_household) if household_id is None: log.info( 'No destination household specified, creating a household for the sim.' ) destination_household = services.household_manager( ).create_household(sim_info.account) else: log.info('Household was specified, getting household of the sim.') destination_household = services.household_manager().get( household_id) if destination_household is None: raise AssertionError('Destination Household not specified!') log.format_info('Destination household acquired', destination_household=destination_household) if CommonSimStateUtils.is_hidden(sim_info): log.info('Making hidden Sim visible.') services.hidden_sim_service().unhide(sim_info.id) if starting_household is destination_household: raise AssertionError( 'The Sim being moved is already in the destination household.') if not destination_household.can_add_sim_info(sim_info): raise AssertionError( 'The destination household has no room for additions.') log.info('Removing Sim from the starting household.') starting_household.remove_sim_info( sim_info, destroy_if_empty_household=destroy_if_empty_household) log.info('Adding Sim to the destination household.') destination_household.add_sim_info_to_household(sim_info) client = services.client_manager().get_first_client() if destination_household is active_household: log.info( 'The destination household is the active household. Changing the Sim to be selectable.' ) client.add_selectable_sim_info(sim_info) else: log.info( 'The destination household is different from the active household. Removing the selectability of the sim.' ) client.remove_selectable_sim_info(sim_info) if sim_info.career_tracker is not None: log.info('Removing invalid careers.') sim_info.career_tracker.remove_invalid_careers() log.info('Invalid careers removed.') sim = sim_info.get_sim_instance() if sim is not None: log.info('Updating sims intended position on the active Lot.') sim.update_intended_position_on_active_lot(update_ui=True) situation_manager = services.get_zone_situation_manager() log.info('Removing Sim from currently active situations.') for situation in situation_manager.get_situations_sim_is_in(sim): if destination_household is active_household and situation.is_user_facing: pass else: log.format_info('Removing situation', situation_id=situation.id) situation_manager.remove_sim_from_situation( sim, situation.id) log.info( 'Done removing situations. Updating daycare service information.' ) services.daycare_service().on_sim_spawn(sim_info) log.info('Done moving Sim to household.') return True
def load_object(self, object_data, **kwargs): self._sim_info = services.sim_info_manager().get(self.sim_id) super().load_object(object_data, **kwargs) if self._sim_info is not None: services.daycare_service().refresh_daycare_status(self._sim_info)