def teleport(self):
     if random.random() > self.chance_to_teleport:
         return
     if self.required_states is not None:
         for state in self.required_states:
             if not self.owner.state_value_active(state):
                 return
     weights_and_commodities = [(obj_dict.weight, obj_dict.static_commodity, obj_dict.state_change) for obj_dict in self.objects_to_teleport_near]
     while weights_and_commodities:
         index = sims4.random._weighted(weights_and_commodities)
         (_, static_commodity, state_change) = weights_and_commodities.pop(index)
         motives = set()
         motives.add(static_commodity)
         all_objects = list(services.object_manager().valid_objects())
         random.shuffle(all_objects)
         for obj in all_objects:
             if obj is self.owner:
                 continue
             if obj.commodity_flags & motives:
                 starting_location = placement.create_starting_location(position=obj.position)
                 if self.owner.is_sim:
                     fgl_context = placement.create_fgl_context_for_sim(starting_location, self.owner)
                 else:
                     fgl_context = placement.create_fgl_context_for_object(starting_location, self.owner)
                 (position, orientation) = placement.find_good_location(fgl_context)
                 if position is not None and orientation is not None:
                     self.owner.transform = sims4.math.Transform(position, orientation)
                     if state_change is not None:
                         obj.set_state(state_change.state, state_change)
                     break
Пример #2
0
 def _do_behavior(self, *args, **kwargs):
     subject = self.interaction.get_participant(self.subject)
     target = self.interaction.get_participant(self.target)
     if subject is None or target is None:
         logger.error(
             'Trying to run a PutNear basic extra with a None Subject and/or Target. subject:{}, target:{}',
             subject,
             target,
             owner='trevor')
         return
     starting_location = placement.create_starting_location(
         location=target.location)
     if subject.is_sim:
         fgl_context = placement.create_fgl_context_for_sim(
             starting_location, subject)
     else:
         fgl_context = placement.create_fgl_context_for_object(
             starting_location, subject)
     (translation, orientation) = placement.find_good_location(fgl_context)
     surface = target.routing_surface
     if translation is None:
         if self.fallback_to_spawn_point:
             zone = services.current_zone()
             fallback_point = zone.get_spawn_point(lot_id=zone.lot.lot_id)
             (translation, orientation) = fallback_point.next_spawn_spot()
             surface = fallback_point.routing_surface
     if translation is not None:
         subject.move_to(translation=translation,
                         orientation=orientation or subject.orientation,
                         routing_surface=surface,
                         parent=None,
                         joint_name_or_hash=None,
                         slot_hash=0)
Пример #3
0
 def _run_interaction_gen(self, timeline):
     if not self._teleporting:
         return True
         yield
     starting_loc = placement.create_starting_location(
         transform=self.target.transform,
         routing_surface=self.target.routing_surface)
     if self.target_jig is not None:
         fgl_context = placement.create_fgl_context_for_object(
             starting_loc, self.target_jig)
     else:
         fgl_context = placement.create_fgl_context_for_sim(
             starting_loc, self.sim)
     (position, orientation) = placement.find_good_location(fgl_context)
     if position is None:
         return False
         yield
     end_transform = sims4.math.Transform(position, orientation)
     self.sim.routing_component.on_slot = None
     ending_location = sims4.math.Location(end_transform,
                                           self.target.routing_surface)
     self.sim.location = ending_location
     self.sim.refresh_los_constraint()
     return True
     yield
Пример #4
0
 def place_puddle(self, target, max_distance, ids_to_ignore=DEFAULT):
     destroy_puddle = True
     try:
         if ids_to_ignore is DEFAULT:
             ids_to_ignore = (self.id,)
         else:
             ids_to_ignore.append(self.id)
         flags = placement.FGLSearchFlag.ALLOW_GOALS_IN_SIM_POSITIONS
         flags = flags | placement.FGLSearchFlag.ALLOW_GOALS_IN_SIM_INTENDED_POSITIONS
         flags = flags | placement.FGLSearchFlag.STAY_IN_SAME_CONNECTIVITY_GROUP
         if target.is_on_active_lot():
             flags = flags | placement.FGLSearchFlag.SHOULD_TEST_BUILDBUY
         else:
             flags = flags | placement.FGLSearchFlag.SHOULD_TEST_ROUTING
             flags = flags | placement.FGLSearchFlag.USE_SIM_FOOTPRINT
         flags = flags | placement.FGLSearchFlag.CALCULATE_RESULT_TERRAIN_HEIGHTS
         flags = flags | placement.FGLSearchFlag.DONE_ON_MAX_RESULTS
         radius_target = target
         while radius_target.parent is not None:
             radius_target = radius_target.parent
         if radius_target.is_part:
             radius_target = radius_target.part_owner
         routing_surface = target.routing_surface
         routing_surface = SurfaceIdentifier(routing_surface.primary_id, routing_surface.secondary_id, SurfaceType.SURFACETYPE_WORLD)
         starting_location = placement.create_starting_location(position=target.position + target.forward*radius_target.object_radius, orientation=sims4.random.random_orientation(), routing_surface=routing_surface)
         fgl_context = placement.create_fgl_context_for_object(starting_location, self, search_flags=flags, ignored_object_ids=ids_to_ignore, max_distance=max_distance)
         (position, orientation) = placement.find_good_location(fgl_context)
         if position is not None:
             destroy_puddle = False
             self.place_puddle_at(position, orientation, routing_surface)
             return True
         return False
     finally:
         if destroy_puddle:
             self.destroy(source=self, cause='Failed to place puddle.')
Пример #5
0
 def get_save_lot_coords_and_level(self):
     lot_coord_msg = LotCoord()
     parent = self.parent
     if parent is not None and parent.is_sim:
         parent.force_update_routing_location()
         starting_position = parent.position + parent.forward
         starting_location = placement.create_starting_location(position=starting_position, orientation=parent.orientation, routing_surface=self.location.world_routing_surface)
         fgl_context = placement.create_fgl_context_for_object(starting_location, self)
         (trans, orient) = placement.find_good_location(fgl_context)
         if trans is None:
             logger.warn('Unable to find good location to save object{}, which is parented to sim {} and cannot go into an inventory. Defaulting to location of sim.', self, parent)
             transform = parent.transform
         else:
             transform = sims4.math.Transform(trans, orient)
         if self.persistence_group == PersistenceGroups.OBJECT:
             transform = services.current_zone().lot.convert_to_lot_coordinates(transform)
     elif self.persistence_group == PersistenceGroups.OBJECT:
         transform = services.current_zone().lot.convert_to_lot_coordinates(self.transform)
     else:
         transform = self.transform
     lot_coord_msg.x = transform.translation.x
     lot_coord_msg.y = transform.translation.y
     lot_coord_msg.z = transform.translation.z
     lot_coord_msg.rot_x = transform.orientation.x
     lot_coord_msg.rot_y = transform.orientation.y
     lot_coord_msg.rot_z = transform.orientation.z
     lot_coord_msg.rot_w = transform.orientation.w
     if self.location.world_routing_surface is not None:
         level = self.location.level
     else:
         level = 0
     return (lot_coord_msg, level)
 def _on_fruit_fall_to_ground(self, fruit):
     plant = self.owner
     if fruit.parent is not plant:
         return False
     if not plant.is_on_active_lot():
         return False
     starting_location = placement.create_starting_location(
         position=plant.position, routing_surface=plant.routing_surface)
     fgl_context = placement.create_fgl_context_for_object(
         starting_location, fruit, ignored_object_ids=(fruit.id, ))
     (position, orientation) = placement.find_good_location(fgl_context)
     if position is None or orientation is None:
         return False
     fruit.move_to(parent=None,
                   translation=position,
                   orientation=orientation,
                   routing_surface=plant.routing_surface)
     owner = plant.get_household_owner_id()
     if owner is not None:
         fruit.set_household_owner_id(owner)
     decay_commodity = GardeningTuning.FRUIT_DECAY_COMMODITY
     fruit.set_stat_value(
         decay_commodity,
         GardeningTuning.FRUIT_DECAY_COMMODITY_DROPPED_VALUE)
     return True
Пример #7
0
    def __call__(self, sim):
        def _abort(vehicle_obj):
            sim.allow_opacity_change = True
            sim.fade_in()
            if vehicle_obj is not None:
                vehicle_obj.destroy()

        vehicle = None
        if sim.sim_info.favorites_tracker is not None:
            favorites_tracker = sim.sim_info.favorites_tracker
            definition_manager = services.definition_manager()
            vehicle_def_id = favorites_tracker.get_favorite_definition_id(
                self.vehicle_obj_tag)
            if vehicle_def_id is not None:
                vehicle_def = definition_manager.get(vehicle_def_id)
                if vehicle_def is not None:
                    vehicle = objects.system.create_object(vehicle_def)
        if vehicle is None:
            if self.fallback_vehicle_def is None:
                _abort(vehicle)
                return True
            vehicle = create_object(self.fallback_vehicle_def)
            if vehicle is None:
                _abort(vehicle)
                return True
        vehicle.set_household_owner_id(sim.household_id)
        starting_location = placement.create_starting_location(
            position=sim.position)
        fgl_context = placement.create_fgl_context_for_object(
            starting_location, vehicle)
        (position, orientation) = placement.find_good_location(fgl_context)
        if position is None or orientation is None:
            _abort(vehicle)
            return True
        vehicle.transform = sims4.math.Transform(position, orientation)
        result = vehicle.vehicle_component.push_drive_affordance(
            sim, priority=Priority.Critical)
        if result is None:
            _abort(vehicle)
            return True
        if result.interaction is None:
            logger.warn(
                "Vehicle's push drive affordance {} resulted in a None interaction. Result: {}.",
                vehicle.vehicle_component.drive_affordance,
                result,
                owner='jmorrow')
            _abort(vehicle)
            return True
        sim.fade_in()
        vehicle.claim()
        for situation in services.get_zone_situation_manager().get_all():
            if sim in situation.all_sims_in_situation_gen():
                situation.manage_vehicle(vehicle)
                break
        return True
Пример #8
0
 def _place_object_on_ground(self, head_obj, source_obj):
     starting_location = create_starting_location(
         location=source_obj.location)
     search_flags = FGLSearchFlag.ALLOW_GOALS_IN_SIM_INTENDED_POSITIONS | FGLSearchFlag.ALLOW_GOALS_IN_SIM_POSITIONS
     fgl_context = placement.create_fgl_context_for_object(
         starting_location,
         head_obj,
         search_flags=search_flags,
         ignored_object_ids=(source_obj.id, ))
     (translation, orientation) = find_good_location(fgl_context)
     if translation is None or orientation is None:
         return False
     head_obj.move_to(translation=translation,
                      orientation=orientation,
                      routing_surface=source_obj.routing_surface)
     return True
Пример #9
0
 def _restore_crate(self):
     if self._pet_crate_x is None:
         return
     obj = create_object(self.pet_crate_object_definition)
     if obj is None:
         return
     position = sims4.math.Vector3(float(self._pet_crate_x),
                                   float(self._pet_crate_y),
                                   float(self._pet_crate_z))
     starting_location = placement.create_starting_location(
         position=position)
     fgl_context = placement.create_fgl_context_for_object(
         starting_location, obj, ignored_object_ids=(obj.id, ))
     (position, orientation) = placement.find_good_location(fgl_context)
     if position is not None and orientation is not None:
         obj.move_to(translation=position, orientation=orientation)
     else:
         obj.destroy()
Пример #10
0
 def create_collectible_from_lightning_strike(location):
     create_tuning = LightningTuning.STRIKE_TERRAIN_TUNING.create_object_tuning
     weighted_items = [(def_weight.weight, def_weight.definition) for def_weight in create_tuning.definition_weights]
     obj_def = sims4.random.weighted_random_item(weighted_items)
     search_flags = placement.FGLSearchFlag.STAY_IN_CONNECTED_CONNECTIVITY_GROUP | placement.FGLSearchFlag.CALCULATE_RESULT_TERRAIN_HEIGHTS | placement.FGLSearchFlag.DONE_ON_MAX_RESULTS | placement.FGLSearchFlag.ALLOW_GOALS_IN_SIM_POSITIONS
     starting_location = placement.create_starting_location(location=location)
     fgl_context = placement.create_fgl_context_for_object(starting_location, obj_def, search_flags=search_flags)
     (new_position, new_orientation) = placement.find_good_location(fgl_context)
     if new_position is None or new_orientation is None:
         logger.info('No good location found for {} from a lightning strike at {}.', obj_def, location, owner='rmccord')
         return
     new_location = sims4.math.Location(sims4.math.Transform(new_position, new_orientation), location.routing_surface)
     created_obj = objects.system.create_object(obj_def)
     if created_obj is not None:
         created_obj.opacity = 0
         created_obj.fade_in()
         created_obj.set_location(new_location)
         created_obj.set_household_owner_id(None)
Пример #11
0
 def try_to_place_bassinet(position, routing_surface=None, **kwargs):
     starting_location = placement.create_starting_location(
         position=position, routing_surface=routing_surface)
     fgl_context = placement.create_fgl_context_for_object(
         starting_location, self, **kwargs)
     (translation,
      orientation) = placement.find_good_location(fgl_context)
     if translation is not None and orientation is not None:
         if is_active_zone_a_plex and (
                 routing_surface is None
                 or plex_service.get_plex_zone_at_position(
                     translation,
                     routing_surface.secondary_id) is None):
             return False
         else:
             self.move_to(translation=translation,
                          orientation=orientation)
             if routing_surface is not None:
                 self.move_to(routing_surface=routing_surface)
             return True
     return False
Пример #12
0
 def get_routes_gen(self):
     routing_surface = self._obj.routing_surface
     routing_surface = SurfaceIdentifier(routing_surface.primary_id,
                                         routing_surface.secondary_id,
                                         self.surface_type_override)
     starting_location = placement.create_starting_location(
         transform=self._obj.location.transform,
         routing_surface=routing_surface)
     fgl_context = placement.create_fgl_context_for_object(
         starting_location, self._obj)
     (position, orientation) = find_good_location(fgl_context)
     if self.surface_type_override is not None and position is None or orientation is None:
         return False
         yield
     if vector3_almost_equal(position, starting_location.position):
         return True
         yield
     goal = Goal(
         routing.Location(position, orientation,
                          starting_location.routing_surface))
     routing_context = self._obj.get_routing_context()
     route = routing.Route(self._obj.routing_location, (goal, ),
                           routing_context=routing_context)
     yield route
Пример #13
0
 def get_fgl_at_destination_for_teleport(cls,
                                         ideal_location,
                                         destination_object,
                                         destination_must_be_outside=False,
                                         ignore_connectivity=False):
     search_flags = placement.FGLSearchFlagsDefault
     if destination_must_be_outside:
         search_flags |= placement.FGLSearchFlag.STAY_OUTSIDE
     fgl_context = None
     if destination_object.is_sim:
         search_flags |= placement.FGLSearchFlagsDefaultForSim
         if ignore_connectivity:
             search_flags &= ~placement.FGLSearchFlag.STAY_IN_CONNECTED_CONNECTIVITY_GROUP
         fgl_context = placement.create_fgl_context_for_sim(
             ideal_location, destination_object, search_flags=search_flags)
     else:
         search_flags |= placement.FGLSearchFlagsDefaultForObject
         if ignore_connectivity:
             search_flags &= ~placement.FGLSearchFlag.STAY_IN_CONNECTED_CONNECTIVITY_GROUP
         fgl_context = placement.create_fgl_context_for_object(
             ideal_location, destination_object, search_flags=search_flags)
     if fgl_context is not None:
         return placement.find_good_location(fgl_context)
     return (None, None)
Пример #14
0
 def _create_object_on_ground(self, spawner_data, max_distance,
                              min_distance, force_initialization_spawn):
     source_object = self.owner
     spawn_list = list(spawner_data.object_reference)
     parent_loc_type = self._get_inherited_spawn_location_type()
     starting_location_tuning = spawner_data.spawner_option.starting_location
     if spawner_data.spawner_option.starting_location.location_type == SpawnerTuning.PORTAL_LOCATION:
         portal_component = self.owner.get_component(PORTAL_COMPONENT)
         if portal_component is None:
             logger.error(
                 "Trying to spawn objects relative to a portal position and the spawner object ({}) doesn't have a portal component. No objects will be spawned.",
                 self.owner)
             return
         portal_location = portal_component.get_portal_location_by_type(
             starting_location_tuning.portal_type,
             starting_location_tuning.portal_direction,
             starting_location_tuning.portal_location)
         if portal_location is None:
             logger.error(
                 'Unable to find a location relative to the specified portal type, location, and direction. No objects will be spawned.'
             )
             return
     if starting_location_tuning.location_type == SpawnerTuning.PORTAL_LOCATION:
         starting_location = placement.create_starting_location(
             position=portal_location.position,
             routing_surface=portal_location.routing_surface)
     else:
         starting_location = placement.create_starting_location(
             position=source_object.position,
             routing_surface=source_object.routing_surface)
     for obj in spawn_list:
         created_obj_location = sims4.math.Location(
             sims4.math.Transform(source_object.position,
                                  source_object.orientation),
             source_object.routing_surface)
         if source_object.is_on_active_lot():
             fgl_context = placement.create_fgl_context_for_object(
                 starting_location,
                 obj,
                 test_buildbuy_allowed=False,
                 max_distance=max_distance,
                 min_distance=min_distance,
                 height_tolerance=GlobalObjectSpawnerTuning.
                 SPAWN_ON_GROUND_FGL_HEIGHT_TOLERANCE)
         else:
             restrictions = [
                 restriction(location=created_obj_location)
                 for restriction in spawner_data.spawner_option.restrictions
             ] or None
             scoring_functions = [
                 placement_scoring(location=created_obj_location)
                 for placement_scoring in
                 spawner_data.spawner_option.placement_scoring
             ] or None
             ignored_object_ids = (
                 source_object.id,
             ) if not spawner_data.spawner_option.starting_location.consider_source_object_footprint else (
             )
             fgl_context = placement.create_fgl_context_for_object_off_lot(
                 starting_location,
                 None,
                 location=created_obj_location,
                 footprint=obj.definition.get_footprint(),
                 max_distance=max_distance,
                 min_distance=min_distance,
                 height_tolerance=GlobalObjectSpawnerTuning.
                 SPAWN_ON_GROUND_FGL_HEIGHT_TOLERANCE,
                 restrictions=restrictions,
                 scoring_functions=scoring_functions,
                 ignored_object_ids=ignored_object_ids)
         (position, orientation) = placement.find_good_location(fgl_context)
         if position is not None:
             created_obj_location = sims4.math.Location(
                 sims4.math.Transform(position, orientation),
                 starting_location.routing_surface)
             created_obj = spawner_data.create_spawned_object(
                 source_object, obj, loc_type=parent_loc_type)
             if created_obj is None:
                 logger.error(
                     'SpawnerComponent: Spawner {} failed to create object: {}',
                     source_object,
                     obj,
                     owner='shouse')
                 return
             created_obj.location = created_obj_location
             created_obj.opacity = 0
             if force_initialization_spawn:
                 force_states = spawner_data.spawner_option.force_initialization_spawn
                 created_obj.force_spawn_object(
                     spawn_type=SpawnerTuning.SLOT_SPAWNER)
             else:
                 force_states = spawner_data.spawner_option.force_states
             if force_states is not None:
                 for force_state in force_states:
                     created_obj.set_state(force_state.state, force_state)
             created_obj.fade_in()
         else:
             logger.info(
                 'SpawnerComponent: FGL failed, object {} will not spawn for spawner {}',
                 obj.definition, source_object)
Пример #15
0
 def _try_place_object_internal(self,
                                obj,
                                target_obj,
                                resolver,
                                ignored_object_ids=None,
                                **kwargs):
     offset_tuning = self.initial_location_offset
     default_offset = sims4.math.Vector3(offset_tuning.default_offset.x,
                                         offset_tuning.default_offset.y,
                                         offset_tuning.default_offset.z)
     x_range = offset_tuning.x_randomization_range
     z_range = offset_tuning.z_randomization_range
     start_orientation = sims4.random.random_orientation()
     if x_range is not None:
         x_axis = start_orientation.transform_vector(
             sims4.math.Vector3.X_AXIS())
         default_offset += x_axis * random.uniform(x_range.lower_bound,
                                                   x_range.upper_bound)
     if z_range is not None:
         z_axis = start_orientation.transform_vector(
             sims4.math.Vector3.Z_AXIS())
         default_offset += z_axis * random.uniform(z_range.lower_bound,
                                                   z_range.upper_bound)
     offset = sims4.math.Transform(default_offset,
                                   sims4.math.Quaternion.IDENTITY())
     start_position = sims4.math.Transform.concatenate(
         offset, target_obj.transform).translation
     routing_surface = target_obj.routing_surface
     active_lot = services.active_lot()
     search_flags = FGLSearchFlag.CALCULATE_RESULT_TERRAIN_HEIGHTS | FGLSearchFlag.DONE_ON_MAX_RESULTS
     if self.surface_type_override is not None:
         routing_surface = SurfaceIdentifier(routing_surface.primary_id,
                                             routing_surface.secondary_id,
                                             self.surface_type_override)
     else:
         search_flags |= FGLSearchFlag.SHOULD_TEST_ROUTING
     if self.ignore_sim_positions:
         search_flags |= FGLSearchFlag.ALLOW_GOALS_IN_SIM_POSITIONS | FGLSearchFlag.ALLOW_GOALS_IN_SIM_INTENDED_POSITIONS
     if self.in_same_room:
         search_flags |= FGLSearchFlag.STAY_IN_CURRENT_BLOCK
     if self.stay_in_connected_connectivity_group:
         search_flags |= FGLSearchFlag.STAY_IN_CONNECTED_CONNECTIVITY_GROUP
     if self.stay_outside_placement:
         search_flags |= FGLSearchFlag.STAY_OUTSIDE
     raytest_kwargs = {}
     if self.raytest:
         search_flags |= FGLSearchFlag.SHOULD_RAYTEST
         raytest_kwargs.update({
             'raytest_radius':
             self.raytest.raytest_radius,
             'raytest_start_offset':
             self.raytest.raytest_start_height_offset,
             'raytest_end_offset':
             self.raytest.raytest_end_height_offset
         })
         if self.raytest.starting_position is not None:
             raytest_target = resolver.get_participant(
                 self.raytest.starting_position)
             if raytest_target is not None:
                 if raytest_target.is_sim:
                     raytest_target = raytest_target.get_sim_instance(
                         allow_hidden_flags=ALL_HIDDEN_REASONS)
                 raytest_kwargs[
                     'raytest_start_point_override'] = raytest_target.transform.translation
     restrictions = None
     if self.facing is not None:
         if self.facing.target is None:
             facing_target = target_obj
         else:
             facing_target = resolver.get_participant(self.facing.target)
         if facing_target is not None:
             restriction = sims4.geometry.RelativeFacingRange(
                 facing_target.position, self.facing.angle)
             restrictions = (restriction, )
     terrain_tags = list(self.terrain_tags) if self.terrain_tags else []
     if self.allow_off_lot_placement and not active_lot.is_position_on_lot(
             start_position):
         obj.location = sims4.math.Location(
             sims4.math.Transform(start_position, start_orientation),
             routing_surface)
         starting_location = create_starting_location(
             position=start_position,
             orientation=start_orientation,
             routing_surface=routing_surface)
         context = create_fgl_context_for_object_off_lot(
             starting_location,
             obj,
             terrain_tags=terrain_tags,
             search_flags=search_flags,
             ignored_object_ids=(obj.id, ),
             restrictions=restrictions,
             min_water_depth=self.min_water_depth,
             max_water_depth=self.max_water_depth,
             **raytest_kwargs)
     else:
         if not self.allow_off_lot_placement and not active_lot.is_position_on_lot(
                 start_position):
             return False
         if not self.ignore_bb_footprints:
             if routing_surface.type != SurfaceType.SURFACETYPE_WORLD:
                 search_flags |= FGLSearchFlag.SHOULD_TEST_BUILDBUY
             else:
                 search_flags |= FGLSearchFlag.SHOULD_TEST_BUILDBUY | FGLSearchFlag.STAY_IN_CURRENT_BLOCK
             if not active_lot.is_position_on_lot(start_position):
                 start_position = active_lot.get_default_position(
                     position=start_position)
             else:
                 position_inside_plex = self._get_plex_postion_for_object_creation(
                     start_position, routing_surface.secondary_id)
                 if position_inside_plex is not None:
                     start_position = position_inside_plex
         starting_location = create_starting_location(
             position=start_position,
             orientation=start_orientation,
             routing_surface=routing_surface)
         pos_increment_info = PositionIncrementInfo(
             position_increment=self.POSITION_INCREMENT,
             from_exception=False)
         context = create_fgl_context_for_object(
             starting_location,
             obj,
             terrain_tags=terrain_tags,
             search_flags=search_flags,
             ignored_object_ids=ignored_object_ids,
             position_increment_info=pos_increment_info,
             restrictions=restrictions,
             min_water_depth=self.min_water_depth,
             max_water_depth=self.max_water_depth,
             **raytest_kwargs)
     if self.perform_fgl_check:
         (translation, orientation) = find_good_location(context)
         if translation is not None:
             obj.move_to(routing_surface=routing_surface,
                         translation=translation,
                         orientation=orientation)
             return True
     elif starting_location is not None:
         obj.move_to(routing_surface=routing_surface,
                     translation=starting_location.position,
                     orientation=starting_location.orientation)
         return True
     return False
Пример #16
0
    def _apply_to_subject_and_target(self, subject, target, resolver):
        if not self._fruits_to_sprout_from:
            return
        weighted_fruit_definitions = list(
            (weighted_fruit.weight.get_multiplier(resolver),
             weighted_fruit.fruit)
            for weighted_fruit in self._fruits_to_sprout_from)
        fruit_to_germinate = sims4.random.pop_weighted(
            weighted_fruit_definitions)
        parent_slot = None
        if not subject.is_terrain:
            runtime_slots = tuple(subject.get_runtime_slots_gen())
            fruit_to_try = fruit_to_germinate
            fruit_to_germinate = None
            while fruit_to_germinate is None:
                for slot in runtime_slots:
                    if not slot.empty:
                        continue
                    if slot.is_valid_for_placement(definition=fruit_to_try):
                        fruit_to_germinate = fruit_to_try
                        parent_slot = slot
                        break
                if fruit_to_germinate is not None:
                    break
                if not weighted_fruit_definitions:
                    break
                fruit_to_try = sims4.random.pop_weighted(
                    weighted_fruit_definitions)

        def post_add(obj):
            obj.transient = True
            obj.visibility = VisibilityState(visibility=False,
                                             inherits=False,
                                             enable_drop_shadow=False)

        created_fruit = create_object(fruit_to_germinate, post_add=post_add)
        if created_fruit is None:
            logger.error(
                f'Error occurred creating {fruit_to_germinate} in {self}')
            return
        if created_fruit.gardening_component is None:
            logger.error(
                f'{created_fruit} is a fruit with no fruit gardening component tuned in {self}'
            )
            return
        if parent_slot is None:
            starting_location = placement.create_starting_location(
                position=subject.position,
                routing_surface=subject.routing_surface)
            fgl_context = placement.create_fgl_context_for_object(
                starting_location,
                created_fruit,
                ignored_object_ids=(created_fruit.id, ))
            (position, orientation) = placement.find_good_location(fgl_context)
            if position is None or orientation is None:
                logger.warn(
                    f'Could not find good location for {created_fruit} using starting location {starting_location}'
                )
                return
            created_fruit.move_to(translation=position,
                                  orientation=orientation,
                                  routing_surface=subject.routing_surface)
        else:
            parent_slot.add_child(created_fruit)
        created_plant = created_fruit.gardening_component.germinate()
        if not created_plant:
            logger.error(f'Failed to germinate {created_fruit}')
            return
        for state_to_set in self._states_to_set_on_plant:
            created_plant.set_state(state_to_set.state, state_to_set)
        if created_plant.gardening_component is None:
            logger.error(
                f'{created_plant} was germinated but had no gardening component!'
            )
            return
        if resolver.interaction:
            resolver.interaction.context.create_target_override = created_plant