예제 #1
0
 def get_edge_constraint(self,
                         constraint_width=1.0,
                         inward_dir=False,
                         return_constraint_list=False,
                         los_reference_point=DEFAULT,
                         sim=None):
     constraint_list = []
     if inward_dir:
         constraint_list.append(SWIM_AT_NONE_CONSTRAINT)
         routing_surface = SurfaceIdentifier(services.current_zone_id(), 0,
                                             SurfaceType.SURFACETYPE_POOL)
         interval = WaterDepthIntervals.SWIM
     else:
         constraint_list.append(STAND_AT_NONE_CONSTRAINT)
         routing_surface = SurfaceIdentifier(services.current_zone_id(), 0,
                                             SurfaceType.SURFACETYPE_WORLD)
         interval = WaterDepthIntervals.WET
     constraint = OceanStartLocationConstraint.create_simple_constraint(
         interval,
         constraint_width,
         sim,
         routing_surface=routing_surface,
         los_reference_point=los_reference_point)
     if not constraint.valid:
         constraint = ANYWHERE
     if return_constraint_list:
         constraint_list.append(constraint)
         return constraint_list
     for other_constraint in constraint_list:
         constraint = constraint.intersect(other_constraint)
     return constraint
예제 #2
0
def add_zone_modifier(zone_modifier: TunableInstanceParam(
    sims4.resources.Types.ZONE_MODIFIER),
                      target_zone_id: int = None,
                      _connection=None):
    if target_zone_id is None:
        target_zone_id = services.current_zone_id()
    persistence_service = services.get_persistence_service()
    zone_data = persistence_service.get_zone_proto_buff(
        services.current_zone_id())
    if zone_data is None:
        return
    if len(zone_data.lot_traits) == ZONE_MODIFIER_CAP:
        sims4.commands.output(
            'There are already {} lot traits on the lot.  Remove one first.'.
            format(ZONE_MODIFIER_CAP), _connection)
        return
    zone_modifier_id = zone_modifier.guid64
    if zone_modifier_id in zone_data.lot_traits:
        sims4.commands.output(
            '{} is already a trait on the lot.'.format(zone_modifier),
            _connection)
        return
    zone_data.lot_traits.append(zone_modifier_id)
    services.get_zone_modifier_service(
    ).check_for_and_apply_new_zone_modifiers(target_zone_id)
예제 #3
0
 def __init__(self, obj, routing_surface, orientation, *args, **kwargs):
     translation = self.get_translation(obj)
     self._tuned_orientation = orientation
     orientation = self.get_orientation(obj)
     if routing_surface == ROUTING_SURFACE_TERRAIN:
         routing_surface = obj.routing_surface
     elif routing_surface == ROUTING_SURFACE_OBJECT:
         routing_surface = obj.provided_routing_surface
     elif routing_surface == ROUTING_SURFACE_GLOBAL_OBJECT:
         routing_surface = SurfaceIdentifier(
             services.current_zone_id(), obj.routing_surface.secondary_id,
             SurfaceType.SURFACETYPE_OBJECT)
     elif routing_surface == ROUTING_SURFACE_OCEAN:
         routing_surface = SurfaceIdentifier(services.current_zone_id(), 0,
                                             SurfaceType.SURFACETYPE_POOL)
     override_level = kwargs.get('override_level')
     if override_level is not None:
         routing_surface = SurfaceIdentifier(routing_surface.primary_id,
                                             override_level,
                                             routing_surface.type)
     terrain_object = services.terrain_service.terrain_object()
     translation.y = terrain_object.get_routing_surface_height_at(
         translation.x, translation.z, routing_surface)
     super().__init__(translation,
                      orientation=orientation,
                      routing_surface=routing_surface)
예제 #4
0
 def validate_household_sim(test_sim):
     if test_sim in self._ss3_requests or test_sim in self.special_case_sims:
         return True
     if test_sim.is_selectable:
         run_affordance = self.species_interaction_speed_requirements.species_affordance_mapping.get(
             test_sim.species)
         if run_affordance is not None:
             self.special_case_sims[test_sim] = run_affordance
             return True
         else:
             roommate_service = services.get_roommate_service()
             if roommate_service is not None and roommate_service.get_home_zone_id(
                     test_sim.sim_id
             ) == services.current_zone_id():
                 run_affordance = roommate_service.get_ss3_affordance(
                 )
                 if run_affordance is not None:
                     self.special_case_sims[
                         test_sim] = run_affordance
                     return True
     else:
         roommate_service = services.get_roommate_service()
         if roommate_service is not None and roommate_service.get_home_zone_id(
                 test_sim.sim_id) == services.current_zone_id():
             run_affordance = roommate_service.get_ss3_affordance(
             )
             if run_affordance is not None:
                 self.special_case_sims[
                     test_sim] = run_affordance
                 return True
     return False
예제 #5
0
 def populate_mannequin_protocol_buffer(mannequin_component):
     persistence_service = services.get_persistence_service()
     current_zone_id = services.current_zone_id()
     sim_info_data_proto = persistence_service.add_mannequin_proto_buff(
     )
     sim_info_data_proto.zone_id = services.current_zone_id()
     sim_info_data_proto.world_id = persistence_service.get_world_id_from_zone(
         current_zone_id)
     mannequin_component.populate_sim_info_data_proto(
         sim_info_data_proto)
     mannequin_component._resend_mannequin_data()
예제 #6
0
def remove_all_zone_modifiers(target_zone_id: int = None, _connection=None):
    if target_zone_id is None:
        target_zone_id = services.current_zone_id()
    persistence_service = services.get_persistence_service()
    zone_data = persistence_service.get_zone_proto_buff(
        services.current_zone_id())
    if zone_data is None:
        return
    traits_to_remove = list(zone_data.lot_traits)
    for trait in traits_to_remove:
        zone_data.lot_traits.remove(trait)
    services.get_zone_modifier_service(
    ).check_for_and_apply_new_zone_modifiers(target_zone_id)
예제 #7
0
def get_routing_surface_at_or_below_position(position):
    for level in range(build_buy.get_highest_level_allowed(),
                       build_buy.get_lowest_level_allowed() - 1, -1):
        if build_buy.has_floor_at_location(position, level):
            break
    return SurfaceIdentifier(services.current_zone_id(), level,
                             SurfaceType.SURFACETYPE_WORLD)
예제 #8
0
 def get_nearest_constraint_start_location(self, species, age,
                                           start_position,
                                           interval: WaterDepthIntervals):
     surface_type = None
     if interval == WaterDepthIntervals.WALK or interval == WaterDepthIntervals.WET or interval == WaterDepthIntervals.WADE:
         surface_type = SurfaceType.SURFACETYPE_WORLD
     elif interval == WaterDepthIntervals.SWIM:
         surface_type = SurfaceType.SURFACETYPE_POOL
     else:
         logger.error('Unhandled water depth interval {}'.format(interval))
     surface_id = SurfaceIdentifier(services.current_zone_id(), 0,
                                    surface_type)
     if interval == WaterDepthIntervals.WALK:
         interval = WaterDepthIntervals.WADE
     key = (species, age, interval)
     if key not in self._constraint_starts:
         return
     else:
         starts = self._constraint_starts[key]
         if starts:
             best_start = starts[0]
             best_distSq = (start_position -
                            best_start.translation).magnitude_squared()
             for start in starts[1:]:
                 distSq = (start_position -
                           start.translation).magnitude_squared()
                 if distSq < best_distSq:
                     best_start = start
                     best_distSq = distSq
             return Location(best_start, surface_id)
예제 #9
0
def c_api_client_connect(session_id,
                         account_id,
                         household_id,
                         persona_name,
                         zone_id,
                         callback,
                         active_sim_id,
                         locale='none',
                         edit_lot_mode=False):
    account = services.account_service().get_account_by_id(
        account_id, try_load_account=True)
    if account is None:
        account = server.account.Account(account_id, persona_name)
    account.locale = locale
    TelemetryTuning.filter_tunable_hooks()
    zone = services.current_zone()
    client = zone.client_manager.create_client(session_id, account,
                                               household_id)
    zone.on_client_connect(client)
    services.on_client_connect(client)
    yield_zone_id(services.current_zone_id())
    if client.household_id == SYSTEM_HOUSEHOLD_ID:
        zone.game_clock.restore_saved_clock_speed()
        return NO_HOUSEHOLD_ERROR_CODE
    status.info('Client {:#08x} ({}) connected to zone {:#08x}'.format(
        session_id, persona_name, zone_id))
    if edit_lot_mode:
        result = zone.do_build_mode_zone_spin_up(household_id)
    else:
        result = zone.do_zone_spin_up(household_id, active_sim_id)
    if not result:
        return EXCEPTION_ERROR_CODE
    return SUCCESS_CODE
 def resume(self):
     if not self.should_resume():
         return
     if services.current_zone_id() == self._zone_id:
         self._resume_venue_behavior()
     self._duration_alarm_handle = self.schedule_duration_alarm(
         self._on_venue_event_complete)
예제 #11
0
 def _replace_object(self, resolver):
     original_obj = resolver.get_participant(self.participant)
     if original_obj is None or original_obj.is_sim:
         return
     new_obj_def = build_buy.get_replacement_object(
         services.current_zone_id(),
         original_obj.id,
         self.number_replacement_attempts,
         self.margin_of_error,
         tags=self.tags,
         exclude_tags=self.exclude_tags)
     if new_obj_def is not None:
         new_obj = objects.system.create_object(new_obj_def)
         if new_obj is not None:
             household_owner_id = original_obj.household_owner_id
             parent_slot = original_obj.parent_slot
             new_obj.move_to(routing_surface=original_obj.routing_surface,
                             translation=original_obj.position,
                             orientation=original_obj.orientation)
             new_obj.set_household_owner_id(household_owner_id)
             if parent_slot is not None:
                 original_obj.set_parent(None)
                 parent_slot.add_child(new_obj)
             delete_liability = DeleteObjectLiability([original_obj])
             self.interaction.add_liability(DELETE_OBJECT_LIABILITY,
                                            delete_liability)
         else:
             logger.warn(
                 'Sim Ray could not create an object from the returned definition: {}.',
                 new_obj_def,
                 owner='jwilkinson')
     else:
         logger.warn(
             'Sim Ray server call did not return a replacement object definition. Try adjusting the tuning to use a larger margin of error.',
             owner='jwilkinson')
 def set_restriction(self, sim_info, game_objects, preference_tag,
                     should_force):
     zone_preference_data = self._zone_object_preference_datas[(
         services.current_zone_id(), preference_tag)]
     if not should_force and sim_info.sim_id in zone_preference_data:
         return
     object_id = None
     subroot_index = None
     for game_object in game_objects:
         object_id = game_object.id
         if game_object.is_part and game_object.restrict_autonomy_preference:
             subroot_index = game_object.subroot_index
         else:
             subroot_index = None
         if zone_preference_data.get_restricted_sim(
                 object_id, subroot_index) is not None:
             continue
         break
     else:
         if not should_force:
             return
     if object_id is not None:
         old_sim_id = zone_preference_data.set_restriction(
             object_id, subroot_index, sim_info.sim_id)
         if old_sim_id is not None:
             roommate_service = services.get_roommate_service()
             if roommate_service is not None:
                 roommate_service.assign_bed(old_sim_id)
         game_object.update_object_tooltip()
예제 #13
0
    def get_hangout_zone_id(self, prefer_current=False):
        if self.hangout_setting == ClubHangoutSetting.HANGOUT_NONE:
            return 0
        if self.hangout_setting == ClubHangoutSetting.HANGOUT_VENUE:
            current_region = services.current_region()

            def is_valid_zone_id(zone_id):
                if not self.is_zone_valid_for_gathering(zone_id):
                    return False
                zone_region = get_region_instance_from_zone_id(zone_id)
                if zone_region is None:
                    return False
                elif not current_region.is_region_compatible(zone_region):
                    return False
                return True

            venue_service = services.venue_service()
            available_zone_ids = tuple(
                filter(
                    is_valid_zone_id,
                    venue_service.get_zones_for_venue_type_gen(
                        self.hangout_venue)))
            for venue in self.hangout_venue.included_venues_for_club_gathering:
                included_zone_ids = tuple(
                    filter(is_valid_zone_id,
                           venue_service.get_zones_for_venue_type_gen(venue)))
                available_zone_ids += included_zone_ids
            if not available_zone_ids:
                return 0
            if prefer_current:
                current_zone_id = services.current_zone_id()
                if current_zone_id in available_zone_ids:
                    return current_zone_id
            return random.choice(available_zone_ids)
        return self.hangout_zone_id
예제 #14
0
 def get_waypoint_constraints_gen(self, routing_agent, waypoint_count):
     zone_id = services.current_zone_id()
     object_constraints = defaultdict(list)
     if self.object_tag_generator is not None:
         object_tag_generator = self.object_tag_generator(WaypointContext(self._sim), None)
         for constraint in itertools.chain((object_tag_generator.get_start_constraint(),), object_tag_generator.get_waypoint_constraints_gen(routing_agent, MAX_INT32)):
             level = constraint.routing_surface.secondary_id
             block_id = get_block_id(zone_id, constraint.average_position, level)
             object_constraints[block_id].append(constraint)
     plex_id = services.get_plex_service().get_active_zone_plex_id() or plex_enums.INVALID_PLEX_ID
     block_data = get_all_block_polygons(plex_id)
     polygons = defaultdict(list)
     if self._routing_surface.secondary_id == 0:
         polygons[0] = self._get_polygons_for_lot()
     for (block_id, (polys, level)) in block_data.items():
         if level != self._routing_surface.secondary_id:
             continue
         polygon = CompoundPolygon([Polygon(list(reversed(p))) for p in polys])
         if not polygon.area():
             continue
         polygons[block_id].append((polygon, self._routing_surface))
     if not polygons:
         return False
         yield
     final_constraints = self._get_waypoint_constraints_from_polygons(polygons, object_constraints, waypoint_count)
     final_constraints = self.apply_water_constraint(final_constraints)
     yield from final_constraints
예제 #15
0
 def _constraint_gen(cls,
                     inst,
                     sim,
                     target,
                     *args,
                     to_zone_id=DEFAULT,
                     **kwargs):
     yield from super(__class__,
                      inst if inst is not None else cls)._constraint_gen(
                          sim, target, *args, **kwargs)
     yield services.current_zone().get_spawn_point_ignore_constraint()
     inst_or_cls = inst if inst is not None else cls
     home_zone_id = sim.sim_info.vacation_or_home_zone_id if to_zone_id is DEFAULT else to_zone_id
     if home_zone_id == services.current_zone_id():
         if services.get_door_service().has_front_door():
             yield inst_or_cls.front_door_constraint.create_constraint(sim)
         else:
             yield inst_or_cls.home_spawn_point_constraint.create_constraint(
                 sim, lot_id=services.current_zone().lot.lot_id)
         yield STAND_CONSTRAINT
     elif sim.sim_info.is_child_or_older:
         persistence_service = services.get_persistence_service()
         zone_data = persistence_service.get_zone_proto_buff(home_zone_id)
         if zone_data is not None and zone_data.world_id == services.current_zone(
         ).world_id:
             home_lot_id = zone_data.lot_id
             yield inst_or_cls.home_spawn_point_constraint.create_constraint(
                 sim, lot_id=home_lot_id)
         else:
             yield inst_or_cls.street_spawn_point_constraint.create_constraint(
                 sim)
 def update_preference_if_possible(self, sim_info):
     object_manager = services.object_manager()
     use_preferences = sim_info.autonomy_use_preferences
     sim_id = sim_info.sim_id
     for preference_tag in self.TAGS_TO_CONVERT:
         if preference_tag in use_preferences:
             old_object_id = use_preferences[preference_tag]
             old_object = object_manager.get(old_object_id)
             if old_object is not None:
                 del use_preferences[preference_tag]
                 subroot_index = None
                 zone_preference_data = self._zone_object_preference_datas[(
                     services.current_zone_id(), preference_tag)]
                 if sim_id in zone_preference_data:
                     continue
                 for old_object_part in old_object.parts:
                     if old_object_part.restrict_autonomy_preference:
                         subroot_index = old_object_part.subroot_index
                         existing_sim_id = zone_preference_data.get_restricted_sim(
                             old_object_id, subroot_index)
                         if existing_sim_id is None:
                             break
                 else:
                     if subroot_index is not None:
                         pass
                     else:
                         zone_preference_data.set_restriction(
                             old_object_id, subroot_index, sim_id)
                 zone_preference_data.set_restriction(
                     old_object_id, subroot_index, sim_id)
예제 #17
0
 def check_if_should_test(self, resolver):
     if not self.only_use_result_on_home_zone:
         return True
     active_household = services.active_household()
     if active_household is None:
         return False
     return active_household.home_zone_id == services.current_zone_id()
예제 #18
0
def create_starting_location(position=None,
                             orientation=None,
                             transform=None,
                             routing_surface=None,
                             location=None):
    starting_routing_location = None
    if location is None:
        if routing_surface is None:
            zone_id = services.current_zone_id()
            routing_surface = routing.SurfaceIdentifier(
                zone_id, 0, routing.SurfaceType.SURFACETYPE_WORLD)
        if transform is None:
            if position is None:
                logger.error(
                    'Trying to create a starting location for a FindGoodLocationContext but position is None. If position is going to remain None then either location or transform need to be passed in instead. -trevor'
                )
            if orientation is None:
                orientation = sims4.math.angle_to_yaw_quaternion(0.0)
            starting_routing_location = routing.Location(
                position, orientation, routing_surface)
        else:
            starting_routing_location = routing.Location(
                transform.translation, transform.orientation, routing_surface)
    else:
        starting_routing_location = routing.Location(
            location.transform.translation, location.transform.orientation,
            location.routing_surface or location.world_routing_surface)
    return starting_routing_location
예제 #19
0
 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)
예제 #20
0
 def _apply_altitude(self, v, altitude, routing_surface=None):
     if altitude is None or altitude is KEEP_ALTITUDE:
         return v
     final_surface = routing_surface if routing_surface is not None else self.routing_surface
     if final_surface:
         level = final_surface.secondary_id
     else:
         level = 0
     zone_id = services.current_zone_id()
     world_surface = routing.SurfaceIdentifier(
         zone_id, level, routing.SurfaceType.SURFACETYPE_WORLD)
     water_surface = routing.SurfaceIdentifier(
         zone_id, level, routing.SurfaceType.SURFACETYPE_POOL)
     object_surface = routing.SurfaceIdentifier(
         zone_id, level, routing.SurfaceType.SURFACETYPE_OBJECT)
     world_height = get_terrain_height(v.x,
                                       v.z,
                                       routing_surface=world_surface)
     water_height = get_terrain_height(v.x,
                                       v.z,
                                       routing_surface=water_surface)
     object_height = get_terrain_height(v.x,
                                        v.z,
                                        routing_surface=object_surface)
     h = max(world_height, water_height, object_height)
     if h == routing_constants.INVALID_TERRAIN_HEIGHT:
         h = get_terrain_center().y
     return sims4.math.Vector3(v.x, h + altitude, v.z)
예제 #21
0
 def __call__(self, test_targets=None):
     target_household = None
     if self.household_to_test.household_source == UtilityTest.ACTIVE_LOT_HOUSEHOLD:
         target_household = services.owning_household_of_active_lot()
     elif self.household_to_test.household_source == UtilityTest.ACTIVE_HOUSEHOLD:
         target_household = services.active_household()
     elif self.household_to_test.household_source == UtilityTest.PARTICIPANT_HOUSEHOLD:
         target = next(iter(test_targets), None)
         if target is not None:
             if target.is_sim:
                 target_household = target.household
             else:
                 target_household = services.household_manager().get(target.get_household_owner_id())
     if target_household is not None:
         utilities_manager = services.get_utilities_manager_by_household_id(target_household.id)
     elif self.household_to_test.household_source == UtilityTest.ACTIVE_LOT_HOUSEHOLD and self.household_to_test.consider_non_household_lot:
         utilities_manager = services.get_utilities_manager_by_zone_id(services.current_zone_id())
     else:
         return TestResult(False, 'UtilitiesTest: Required to check utility, but there is no household. Check participant tuning.', tooltip=self.tooltip)
     if utilities_manager is None:
         return TestResult(False, 'UtilitiesTest: Required to check utility, but utilities manager is None. Check participant tuning.', tooltip=self.tooltip)
     for utility_state in self.utility_states:
         if utilities_manager.is_utility_active(utility_state.utility) != utility_state.require_active:
             return TestResult(False, 'UtilitiesTest: Utility status for the {} is not correct.', utility_state.utility, tooltip=self.tooltip)
     return TestResult.TRUE
 def decorate_neighborhood_for_holiday(self,
                                       holiday_id,
                                       decorate_immediately=False,
                                       preset_override=None):
     neighborhood_decoration_state = self.get_neighborhood_state_for_zone(
         services.current_zone_id())
     if neighborhood_decoration_state is None:
         return
     holiday_provider = self._get_decoration_provider(holiday_id)
     for lot in neighborhood_decoration_state.lots:
         if lot.is_owned_by_active_household():
             continue
         resolver = SingleSimResolver(None,
                                      additional_participants={
                                          ParticipantType.PickedZoneId:
                                          (lot.zone_id, )
                                      })
         if any(resolver(test) for test in self.NON_DECORATABLE_TESTS):
             decoration_provider = DEFAULT_DECORATION_PROVIDER
         else:
             decoration_provider = holiday_provider
         lot.switch_to_appropriate_type(
             decoration_provider,
             DECORATE_IMMEDIATELY
             if decorate_immediately else self.AUTO_DECORATION_PARAMS,
             preset_override=preset_override)
     self._update_current_lot_statistic()
     self._world_decorations_set[
         neighborhood_decoration_state.
         world_id] = holiday_provider.decoration_type_id
예제 #23
0
 def _test_zone_id(cls, zone_id):
     if zone_id is None:
         return TestResult(False, 'Could not resolve into a valid zone id.')
     active_household = services.active_household()
     if zone_id == active_household.home_zone_id:
         return TestResult(
             False,
             "Cannot move sim into the active household's home zone.")
     if zone_id == services.current_zone_id():
         return TestResult(False, 'Cannot move Sim into the active zone.')
     plex_service = services.get_plex_service()
     if not plex_service.is_zone_an_apartment(
             zone_id, consider_penthouse_an_apartment=False):
         persistence_service = services.get_persistence_service()
         if persistence_service is None:
             return TestResult(False,
                               'Persistence service is not initialized.')
         zone_data = persistence_service.get_zone_proto_buff(zone_id)
         if zone_data is None:
             return TestResult(False, 'Could not resolve zone data.')
         lot_data = persistence_service.get_lot_data_from_zone_data(
             zone_data)
         if lot_data is None:
             return TestResult(False, 'Could not resolve lot data.')
         venue_tuning = services.get_instance_manager(
             sims4.resources.Types.VENUE).get(lot_data.venue_key)
         if not venue_tuning.is_residential:
             return TestResult(False,
                               'Only residential venues are eligible.')
     return TestResult.TRUE
예제 #24
0
 def _get_affected_household(self):
     household = services.active_household()
     if household is None:
         return
     elif household.home_zone_id != services.current_zone_id():
         return
     return household
예제 #25
0
 def _close_business(self, play_sound=True):
     if not self._is_open:
         return
     if play_sound:
         sound = PlaySound(services.get_active_sim(), self.tuning_data.audio_sting_close.instance)
         sound.start()
     self._employee_manager.close_business()
     self.send_daily_profit_and_cost_update()
     self._send_business_closed_telemetry()
     if self._owner_household_id is not None:
         owner_household = services.household_manager().get(self._owner_household_id)
         owner_household.bucks_tracker.deactivate_all_temporary_perk_timers_of_type(self.tuning_data.bucks)
         self.modify_funds(-self._employee_manager.final_daily_wages(), from_item_sold=False)
     self.on_store_closed()
     services.get_event_manager().process_event(TestEvent.BusinessClosed)
     self._distribute_business_open_status(False)
     if self.business_zone_id == services.current_zone_id():
         self.tuning_data.lighting_helper_close.execute_lighting_helper(self)
         zone_director = services.venue_service().get_zone_director()
         if zone_director is not None:
             zone_director.refresh_open_street_director_status()
     else:
         self.run_off_lot_simulation()
         self._last_off_lot_update = None
     self._is_open = False
     self.show_summary_dialog(is_from_close=True)
     self._open_time = None
예제 #26
0
 def _test(cls, *args, sim_info=None, **kwargs):
     if sim_info.zone_id == services.current_zone_id():
         return TestResult(
             False,
             'Cannot bring a sim to a zone that is already the current zone.'
         )
     return super()._test(*args, **kwargs)
예제 #27
0
 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.')
     return super()._test(*args, **kwargs)
예제 #28
0
 def get_abandoned_toddlers(self, household, sims_infos_to_ignore=()):
     caretaker_zone_ids = set()
     offlot_toddlers = set()
     abandoned_toddlers = []
     current_zone_id = services.current_zone_id()
     for sim_info in household:
         if sim_info in sims_infos_to_ignore:
             continue
         if not sim_info.is_toddler:
             if sim_info.can_live_alone:
                 caretaker_zone_ids.add(sim_info.zone_id)
                 if sim_info.zone_id == current_zone_id:
                     continue
                 if sim_info.zone_id == sim_info.household.home_zone_id:
                     continue
                 offlot_toddlers.add(sim_info)
         else:
             if sim_info.zone_id == current_zone_id:
                 continue
             if sim_info.zone_id == sim_info.household.home_zone_id:
                 continue
             offlot_toddlers.add(sim_info)
     for toddler in offlot_toddlers:
         if toddler.zone_id not in caretaker_zone_ids:
             abandoned_toddlers.append(toddler)
     return abandoned_toddlers
예제 #29
0
 def create_surface_proxy_from_location(location):
     position = location.transform.translation
     zone_id = services.current_zone_id()
     routing_surface = location.routing_surface
     level = routing_surface.secondary_id
     pool_block_id = 0
     if build_buy.is_location_pool(position, level):
         pool_block_id = build_buy.get_block_id(zone_id, position,
                                                level - 1)
         if not pool_block_id:
             logger.error('Failed ot get pool block id from location: {} ',
                          location)
             return
         pool = pool_utils.get_pool_by_block_id(pool_block_id)
         if pool is None:
             logger.error(
                 'Failed to get pool from pool block id {} at location: {}',
                 pool_block_id, location)
             return
         return PoolPoint(location, pool)
     if routing_surface.type == routing.SurfaceType.SURFACETYPE_POOL:
         if services.terrain_service.ocean_object() is None:
             logger.error('Ocean does not exist at location: {}', location)
             return
         return OceanPoint(location)
     return TerrainPoint(location)
예제 #30
0
 def is_daycare_service_npc_available(self, sim_info=None, household=None):
     household = services.active_household() if household is None else household
     if household.home_zone_id == services.current_zone_id():
         nanny_situation = self._get_running_situation_for_service(DaycareTuning.NANNY_SERVICE_NPC)
         if nanny_situation is not None:
             if sim_info is None:
                 return True
             service_sim = nanny_situation.service_sim()
             if service_sim is not None and service_sim.sim_info is sim_info:
                 return True
         if DaycareTuning.BUTLER_SERVICE_NPC is not None:
             butler_situation = self._get_running_situation_for_service(DaycareTuning.BUTLER_SERVICE_NPC)
             if butler_situation is not None:
                 if butler_situation.is_in_childcare_state:
                     if sim_info is None:
                         return True
                     service_sim = butler_situation.service_sim()
                     if service_sim is not None:
                         if service_sim.sim_info is sim_info:
                             return True
     elif sim_info is None:
         all_hired_service_npcs = household.get_all_hired_service_npcs()
         for service_npc in (DaycareTuning.NANNY_SERVICE_NPC, DaycareTuning.BUTLER_SERVICE_NPC):
             if service_npc is None:
                 continue
             if service_npc.guid64 in all_hired_service_npcs:
                 return True
     return False
예제 #31
0
 def _load_household(self, household_id):
     household = self.get(household_id)
     if household is not None:
         for sim_info in household.sim_info_gen():
             zone_id = services.current_zone_id()
             if sim_info.zone_id != zone_id:
                 householdProto = services.get_persistence_service().get_household_proto_buff(household_id)
                 if householdProto is None:
                     logger.error('unable to find household with household id {}'.household_id)
                     return
                 found_sim = False
                 if householdProto.sims.ids:
                     for sim_id in householdProto.sims.ids:
                         if sim_id == sim_info.sim_id:
                             found_sim = True
                             break
                 if found_sim:
                     sim_proto = services.get_persistence_service().get_sim_proto_buff(sim_id)
                     sim_info.load_sim_info(sim_proto)
         return household
     logger.info('Starting to load household id = {0}', household_id)
     household_proto = services.get_persistence_service().get_household_proto_buff(household_id)
     if household_proto is None:
         sims4.log.error('Persistence', 'Household proto could not be found id = {0}', household_id)
         return
     household = self._load_household_from_household_proto(household_proto)
     return household
예제 #32
0
 def _update_walkstyle(self, path, actor, time_offset):
     walkstyle = self._get_walkstyle(actor, path)
     age = actor.age
     gender = actor.gender
     for n in path.nodes:
         while n.time >= time_offset:
             self._apply_rules_to_node(n, walkstyle, actor)
     path.nodes.update_timing(walkstyle, age, gender, time_offset, services.current_zone_id())
 def refresh(self, on_travel_away=False):
     if not self.is_sim_info_valid_to_run_away_actions():
         return
     current_zone = services.current_zone()
     if not current_zone.is_zone_running and not current_zone.are_sims_hitting_their_marks:
         return
     if self._sim_info.zone_id == services.current_zone_id():
         self.stop()
         self._current_away_action = None
     else:
         self.start(on_travel_away=on_travel_away)
예제 #34
0
 def _run_interaction_gen(self, timeline):
     home_zone_id = self.sim.household.home_zone_id
     if home_zone_id == services.current_zone_id():
         return
     client = services.client_manager().get_first_client()
     expect_response = True
     for next_sim_info in client.selectable_sims:
         next_sim = next_sim_info.get_sim_instance(allow_hidden_flags=ALL_HIDDEN_REASONS)
         while next_sim is not self.sim and next_sim is not None:
             expect_response = False
     travel_liability = TravelSimLiability(self, self.sim.sim_info, self.to_zone_id, is_attend_career=self.attend_career)
     if expect_response:
         travel_liability.travel_player()
     else:
         self.add_liability(TRAVEL_SIM_LIABILITY, travel_liability)
예제 #35
0
 def _constraint_gen(cls, inst, sim, target, *args, **kwargs):
     yield super()._constraint_gen(sim, target, *args, **kwargs)
     yield services.current_zone().get_spawn_point_ignore_constraint()
     inst_or_cls = inst if inst is not None else cls
     home_zone_id = sim.household.home_zone_id
     if home_zone_id == services.current_zone_id():
         active_lot = services.current_zone().lot
         if active_lot.front_door_id is not None:
             yield inst_or_cls.front_door_constraint.create_constraint(sim)
         else:
             yield inst_or_cls.home_spawn_point_constraint.create_constraint(sim, lot_id=active_lot.lot_id)
     else:
         persistence_service = services.get_persistence_service()
         zone_data = persistence_service.get_zone_proto_buff(home_zone_id)
         if zone_data.world_id == services.current_zone().world_id:
             home_lot_id = zone_data.lot_id
             yield inst_or_cls.home_spawn_point_constraint.create_constraint(sim, lot_id=home_lot_id)
         else:
             yield inst_or_cls.street_spawn_point_constraint.create_constraint(sim)
 def on_enter(self):
     super().on_enter()
     client = services.client_manager().get_first_client()
     home_zone_id = client.household.home_zone_id
     if home_zone_id == 0:
         return _ZoneSpinUpStateResult.DONE
     zone_manager = services.get_zone_manager()
     loaded_zones = set()
     loaded_zones.add(services.current_zone_id())
     for sim_info in services.sim_info_manager().values():
         if sim_info.is_selectable:
             if sim_info.zone_id not in loaded_zones:
                 zone_manager.load_uninstantiated_zone_data(
                     sim_info.zone_id)
                 loaded_zones.add(sim_info.zone_id)
             sim_info.away_action_tracker.start()
         else:
             sim_info.away_action_tracker.stop()
     home_zone_id = client.household.home_zone_id
     if home_zone_id not in loaded_zones:
         zone_manager.load_uninstantiated_zone_data(home_zone_id)
     return _ZoneSpinUpStateResult.DONE
 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.instance_attr, sim_id=sim_info.id)
         death_object.update_object_tooltip()
         death_object.set_household_owner_id(sim_info.household.id)
         if self._death_object_data[1]:
             build_buy.move_object_to_household_inventory(death_object)
     death_tracker = sim_info.death_tracker
     death_tracker.set_death_type(self.death_type)
     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)
         if not any(sim.is_teen_or_older for sim in self._client.selectable_sims):
             self._show_death_dialog()
             persistence_service = services.get_persistence_service()
             sim_info_manager = services.sim_info_manager()
             for selectable_sim_info in self._client.selectable_sims:
                 sim_id = selectable_sim_info.id
                 sim_to_destroy = selectable_sim_info.get_sim_instance(allow_hidden_flags=ALL_HIDDEN_REASONS)
                 if sim_to_destroy is not None:
                     sim_to_destroy.destroy(source=sim_to_destroy, cause='Last adult sim dieing, destroying dependent sims.')
                 persistence_service.del_sim_proto_buff(sim_id)
                 sim_info_manager.remove_permanently(selectable_sim_info)
             self._client.clear_selectable_sims()
             zone_id = services.current_zone_id()
             current_household.clear_household_lot_ownership(zone_id)
             current_household.hidden = True
             fire_service = services.get_fire_service()
             if fire_service is not None:
                 fire_service.kill()
예제 #38
0
 def get_work_affordance(self):
     if self._sim_info.household.home_zone_id == services.current_zone_id():
         return self.career_affordance
     return self.go_home_to_work_affordance
예제 #39
0
 def should_fade_sim_out(self):
     home_zone_id = self.sim.household.home_zone_id
     if home_zone_id == services.current_zone_id():
         return False
     return True
예제 #40
0
    def generate_path(self, timeline):
        start_time = services.time_service().sim_now
        ticks = 0
        try:
            self.path.status = routing.Path.PLANSTATUS_PLANNING
            self.path.nodes.clear_route_data()
            if not self.route.goals:
                self.path.status = routing.Path.PLANSTATUS_FAILED
            else:
                for goal in self.route.goals:
                    self.path.add_goal(goal)
                for origin in self.route.origins:
                    self.path.add_start(origin)
                self.sim.on_plan_path(self.route.goals, True)
                if self.path.nodes.make_path() is True:

                    def is_planning_done():
                        nonlocal ticks
                        ticks += 1
                        return not self.path.nodes.plan_in_progress

                    yield element_utils.run_child(timeline, elements.BusyWaitElement(soft_sleep_forever(), is_planning_done))
                    self.path.nodes.finalize(self._is_failure_route)
                else:
                    self.path.status = routing.Path.PLANSTATUS_FAILED
                new_route = routing.Route(self.route.origin, self.route.goals, additional_origins=self.route.origins, routing_context=self.route.context)
                new_route.path.copy(self.route.path)
                new_path = routing.Path(self.path.sim, new_route)
                new_path.status = self.path.status
                new_path._start_ids = self.path._start_ids
                new_path._goal_ids = self.path._goal_ids
                result_path = new_path
                if len(new_path.nodes) > 0:
                    start_index = 0
                    current_index = 0
                    for n in self.path.nodes:
                        if n.portal_object_id != 0:
                            portal_object = services.object_manager(services.current_zone_id()).get(n.portal_object_id)
                            if portal_object is not None and portal_object.split_path_on_portal():
                                new_path.nodes.clip_nodes(start_index, current_index)
                                new_route = routing.Route(self.route.origin, self.route.goals, additional_origins=self.route.origins, routing_context=self.route.context)
                                new_route.path.copy(self.route.path)
                                next_path = routing.Path(self.path.sim, new_route)
                                next_path.status = self.path.status
                                next_path._start_ids = self.path._start_ids
                                next_path._goal_ids = self.path._goal_ids
                                new_path.next_path = next_path
                                new_path.portal = portal_object
                                new_path = next_path
                                start_index = current_index + 1
                        current_index = current_index + 1
                    new_path.nodes.clip_nodes(start_index, current_index - 1)
                self.route = result_path.route
                self.path = result_path
                self.sim.on_plan_path(self.route.goals, False)
        except Exception:
            logger.exception('Exception in generate_path')
            self.path.status = routing.Path.PLANSTATUS_FAILED
            self.sim.on_plan_path(self.route.goals, False)
        if self.path.status == routing.Path.PLANSTATUS_PLANNING:
            self.path.set_status(routing.Path.PLANSTATUS_READY)
        else:
            self.path.set_status(routing.Path.PLANSTATUS_FAILED)
        if gsi_handlers.routing_handlers.archiver.enabled:
            gsi_handlers.routing_handlers.archive_plan(self.sim, self.path, ticks, (services.time_service().sim_now - start_time).in_real_world_seconds())
예제 #41
0
 def _apply_walkstyle(self, path, actor):
     walkstyle = self._get_walkstyle(actor, path)
     origin_q = (float(actor.orientation.x), float(actor.orientation.y), float(actor.orientation.z), float(actor.orientation.w))
     origin_t = (float(actor.position.x), float(actor.position.y), float(actor.position.z))
     age = actor.age
     gender = actor.gender
     if actor.allow_running_for_long_distance_routes:
         self._running_nodes = self._determine_running_nodes(path)
     else:
         self._running_nodes = []
     for n in path.nodes:
         self._apply_rules_to_node(n, walkstyle, actor)
     current_ticks = int(services.time_service().sim_now)
     path.nodes.apply_initial_timing(origin_q, origin_t, walkstyle, age, gender, current_ticks, services.current_zone_id())
 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.')
     return super()._test(*args, **kwargs)
 def _test(cls, *args, sim_info=None, **kwargs):
     if sim_info.zone_id == services.current_zone_id():
         return TestResult(False, 'Cannot bring a sim to a zone that is already the current zone.')
     return super()._test(*args, **kwargs)