def generate_jig_polygon(loc_a, pos_a, rotation_a, loc_b, pos_b, rotation_b, a_left, a_right, a_front, a_back, b_left, b_right, b_front, b_back, positioning_type=JigPositioning.RelativeToSimB, fallback_routing_surface=None, reverse_nonreletive_sim_orientation=False, **fgl_kwargs): if isinstance(pos_a, sims4.math.Vector2): pos_a = sims4.math.Vector3(pos_a.x, 0, pos_a.y) if isinstance(pos_b, sims4.math.Vector2): pos_b = sims4.math.Vector3(pos_b.x, 0, pos_b.y) sim_a_radians = rotation_a sim_b_radians = rotation_b def _generate_polygon_params(relative_loc, fwd_vec, relative_vec, rot_relative, rot_other): polygon_fwd = relative_loc.transform.orientation.transform_vector(fwd_vec) abs_vec_to_relative_sim = relative_loc.transform.orientation.transform_vector(relative_vec) translation_relative = relative_loc.world_transform.translation fwd_relative = sims4.math.vector3_rotate_axis_angle(polygon_fwd, rot_relative, sims4.math.Vector3.Y_AXIS()) translation_other = translation_relative - abs_vec_to_relative_sim fwd_other = sims4.math.vector3_rotate_axis_angle(polygon_fwd, rot_other, sims4.math.Vector3.Y_AXIS()) routing_surface = relative_loc.routing_surface if relative_loc.parent is not None: routing_surface = relative_loc.parent.routing_surface start_location = routing.Location(relative_loc.world_transform.translation, relative_loc.world_transform.orientation, routing_surface) return (start_location, fwd_relative, translation_relative, fwd_other, translation_other, routing_surface) if positioning_type == JigPositioning.RelativeToSimB: vec_to_relative_sim = pos_b - pos_a (start_location, sim_b_fwd, sim_b_translation, sim_a_fwd, sim_a_translation, routing_surface) = _generate_polygon_params(loc_b, -1*sims4.math.Vector3.Z_AXIS(), vec_to_relative_sim, sim_b_radians, sim_a_radians) else: vec_to_relative_sim = pos_a - pos_b (start_location, sim_a_fwd, sim_a_translation, sim_b_fwd, sim_b_translation, routing_surface) = _generate_polygon_params(loc_a, sims4.math.Vector3.Z_AXIS(), vec_to_relative_sim, sim_a_radians, sim_b_radians) polygon = _generate_poly_points(sim_a_translation, sim_a_fwd, sim_b_translation, sim_b_fwd, a_left, a_right, a_front, a_back, b_left, b_right, b_front, b_back) context = placement.FindGoodLocationContext(start_location, object_polygons=(polygon,), **fgl_kwargs) (new_translation, new_orientation) = placement.find_good_location(context) if new_translation is None: if fallback_routing_surface is not None: start_location.routing_surface = fallback_routing_surface context = placement.FindGoodLocationContext(start_location, object_polygons=(polygon,), **fgl_kwargs) (new_translation, new_orientation) = placement.find_good_location(context) if new_translation is None: return (None, None, None, None, None) if positioning_type == JigPositioning.RelativeToSimB: sim_b_translation = new_translation sim_b_orientation = sims4.math.Quaternion.concatenate(new_orientation, sims4.math.angle_to_yaw_quaternion(sim_b_radians)) if reverse_nonreletive_sim_orientation: sim_a_fwd = new_orientation.transform_vector(vec_to_relative_sim) else: sim_a_fwd = new_orientation.transform_vector(-1*vec_to_relative_sim) sim_a_translation = new_translation + new_orientation.transform_vector(-1*vec_to_relative_sim) sim_a_orientation = sims4.math.Quaternion.from_forward_vector(sims4.math.vector3_rotate_axis_angle(sim_a_fwd, sim_a_radians, sims4.math.Vector3.Y_AXIS())) else: sim_a_translation = new_translation sim_a_orientation = sims4.math.Quaternion.concatenate(new_orientation, sims4.math.angle_to_yaw_quaternion(sim_a_radians)) if reverse_nonreletive_sim_orientation: sim_b_fwd = new_orientation.transform_vector(vec_to_relative_sim) else: sim_b_fwd = new_orientation.transform_vector(-1*vec_to_relative_sim) sim_b_translation = new_translation + new_orientation.transform_vector(-1*vec_to_relative_sim) sim_b_orientation = sims4.math.Quaternion.concatenate(new_orientation, sims4.math.angle_to_yaw_quaternion(sim_b_radians)) return (sim_a_translation, sim_a_orientation, sim_b_translation, sim_b_orientation, routing_surface)
def snap_to_good_location_on_floor(target, starting_transform=None, starting_routing_surface=None): target.visibility = VisibilityState(True, True, True) parent = target.get_parenting_root() if starting_transform is None: starting_transform = parent.transform starting_transform = sims4.math.Transform( parent.position + parent.forward * parent.object_radius, starting_transform.orientation) if starting_routing_surface is None: starting_routing_surface = parent.routing_surface search_flags = CarryingObject.SNAP_TO_GOOD_LOCATION_SEARCH_FLAGS (trans, orient) = placement.find_good_location( placement.FindGoodLocationContext( starting_transform=starting_transform, starting_routing_surface=starting_routing_surface, object_footprints=(target.footprint, ), object_id=target.id, search_flags=search_flags)) if starting_transform is not None and ( starting_transform.translation != trans or starting_transform.orientation != orient): logger.debug( "snap_to_good_location_on_floor's FGL couldn't use the exact suggested starting transform." ) if trans is not None: target.clear_parent(sims4.math.Transform(trans, orient), starting_routing_surface) return True logger.warn( 'snap_to_good_location_on_floor could not find good location for {}.', target) target.clear_parent(starting_transform, starting_routing_surface) return False
def get_slot_pos(self, index=None): participant = self.get_participant() trans = None if participant is not None: (trans, _) = placement.find_good_location( placement.FindGoodLocationContext( starting_location=participant.location, max_distance=FGLTuning.MAX_FGL_DISTANCE, additional_avoid_sim_radius=routing. get_default_agent_radius(), object_id=participant.id, max_steps=10, offset_distance=self.distance_to_participant, scoring_functions=(placement.ScoringFunctionRadial( participant.location.transform.translation, self.distance_to_participant, 0, FGLTuning.MAX_FGL_DISTANCE), ), search_flags=placement.FGLSearchFlag. STAY_IN_CONNECTED_CONNECTIVITY_GROUP | placement.FGLSearchFlag.SHOULD_TEST_BUILDBUY | placement.FGLSearchFlag.USE_SIM_FOOTPRINT | placement.FGLSearchFlag.CALCULATE_RESULT_TERRAIN_HEIGHTS)) if trans is None: fallback_point = services.current_zone().get_spawn_point( lot_id=self.lot_id) (trans, _) = fallback_point.next_spawn_spot() return trans return trans
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 search_flags = CarryingObject.SNAP_TO_GOOD_LOCATION_SEARCH_FLAGS (trans, orient) = placement.find_good_location(placement.FindGoodLocationContext(starting_position=starting_position, starting_orientation=parent.orientation, starting_routing_surface=self.location.world_routing_surface, object_footprints=(self.footprint,), object_id=self.id, search_flags=search_flags)) 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) 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 _get_terrain_transform(self, interaction): if self.owner.footprint_component is not None: sim = interaction.sim additional_put_down_distance = sim.posture_state.body.additional_put_down_distance starting_position = sim.position + sim.forward * ( sim.object_radius + additional_put_down_distance) sim_los_constraint = sim.lineofsight_component.constraint if not sims4.geometry.test_point_in_compound_polygon( starting_position, sim_los_constraint.geometry.polygon): starting_position = sim.position search_flags = FGLSearchFlag.STAY_IN_CURRENT_BLOCK | FGLSearchFlag.SHOULD_TEST_ROUTING | FGLSearchFlag.CALCULATE_RESULT_TERRAIN_HEIGHTS | FGLSearchFlag.DONE_ON_MAX_RESULTS | FGLSearchFlag.SHOULD_TEST_BUILDBUY MAX_PUTDOWN_STEPS = 8 MAX_PUTDOWN_DISTANCE = 10 (position, orientation) = placement.find_good_location( placement.FindGoodLocationContext( starting_position=starting_position, starting_orientation=sim.orientation, starting_routing_surface=sim.routing_surface, object_footprints=(self.owner.get_footprint(), ), object_id=self.owner.id, max_steps=MAX_PUTDOWN_STEPS, max_distance=MAX_PUTDOWN_DISTANCE, search_flags=search_flags)) if position is not None: put_down_transform = sims4.math.Transform( position, orientation) return put_down_transform
def _run_interaction_gen(self, timeline): obj = objects.system.create_object(self.test_definition) if obj is not None: obj.move_to(translation=self.context.pick.location) (position, orientation) = placement.find_good_location( placement.FindGoodLocationContext( starting_position=self.context.pick.location, ignored_object_ids=(obj.id, ), object_id=obj.id, position_increment=0.6, search_flags=placement.FGLSearchFlagsDefault | placement.FGLSearchFlag.SHOULD_TEST_BUILDBUY | placement.FGLSearchFlag.DONE_ON_MAX_RESULTS | placement.FGLSearchFlag.STAY_IN_CURRENT_BLOCK, object_footprints=(self.test_definition.get_footprint(0), ))) if position is None or orientation is None: if obj is not None: obj.destroy( source=self, cause= 'Failed to find good location in debug find good location interaction.' ) return False loc = sims4.math.Transform(position, orientation) sims4.log.info('Placement', 'Found good location:\n Pos: {0}\n Ori: {1}', position, orientation) if obj is not None: obj.transform = loc return True return False
def _calculate_valid_locations(self): self._valid_attractor_positions.clear() for attractor_tuning in self.attractors: terrain_tags = list(attractor_tuning.terrain_tags ) if attractor_tuning.terrain_tags else [] objects_to_ignore = self._attractor_ids[attractor_tuning] sample_points = services.active_lot( ).get_uniform_sampling_of_points(attractor_tuning.samples_per_axis, attractor_tuning.samples_per_axis) for point in sample_points: starting_location_for_sample = placement.create_starting_location( position=point) placement_polygon = sims4.geometry.generate_circle_constraint( attractor_tuning.placement_circle.number_of_sides, point, attractor_tuning.placement_circle.radius) fgl_context = placement.FindGoodLocationContext( starting_location_for_sample, object_polygons=(placement_polygon, ), ignored_object_ids=objects_to_ignore, max_distance=attractor_tuning.placement_radius, terrain_tags=terrain_tags, min_water_depth=attractor_tuning.min_water_depth, max_water_depth=attractor_tuning.max_water_depth, search_flags=placement.FGLSearchFlagsDefault | placement.FGLSearchFlag.ALLOW_GOALS_IN_SIM_POSITIONS | placement.FGLSearchFlag. ALLOW_GOALS_IN_SIM_INTENDED_POSITIONS) (position, orientation) = placement.find_good_location(fgl_context) if position: self._valid_attractor_positions[attractor_tuning].append( (position, orientation))
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) if self._target is None: self._start_constraint = Nowhere( 'No target for _WaypointGeneratorPacing') self._los_reference_point = None return self._los_reference_point = self._target.position if self._target.is_terrain: self._los_reference_point = None water_constraint = self.get_water_constraint( self.constraint_parameters.min_water_depth, self.constraint_parameters.max_water_depth) if self.outside_only: self._routing_surface = routing.SurfaceIdentifier( services.current_zone_id(), 0, routing.SurfaceType.SURFACETYPE_WORLD) starting_location = Location(position=self._target.position, routing_surface=self._routing_surface) search_flags = FGLSearchFlagsDefaultForSim | FGLSearchFlag.STAY_OUTSIDE fgl_context = placement.FindGoodLocationContext( starting_location, routing_context=self._context.sim.routing_context, additional_avoid_sim_radius=routing.get_default_agent_radius(), max_results=1, max_steps=10, search_flags=search_flags, min_water_depth=water_constraint.get_min_water_depth(), max_water_depth=water_constraint.get_max_water_depth()) (trans, _) = placement.find_good_location(fgl_context) if trans is not None: geometry = sims4.geometry.RestrictedPolygon( sims4.geometry.CompoundPolygon( sims4.geometry.Polygon((trans, ))), ()) self._start_constraint = SmallAreaConstraint( geometry=geometry, debug_name='WaypointPacingStartingConstraint', routing_surface=self._routing_surface, min_water_depth=water_constraint.get_min_water_depth(), max_water_depth=water_constraint.get_max_water_depth()) else: self._start_constraint = Nowhere( 'WaypointGeneratorPacing requires outside, but we failed to find a good location.' ) else: self._start_constraint = Circle( self._target.position, self.constraint_parameters.object_constraint_radius, routing_surface=self._routing_surface, los_reference_point=self._los_reference_point, min_water_depth=water_constraint.get_min_water_depth(), max_water_depth=water_constraint.get_max_water_depth())
def get_waypoint_constraints_gen(self, routing_agent, waypoint_count): line_length_offset = sims4.math.Vector3(0, 0, self.line_length) object_radius = routing_agent.routing_component.object_radius start = routing_agent.position initial_orientation = sims4.random.random_orientation() end = initial_orientation.transform_vector(line_length_offset) + start polygon = build_rectangle_from_two_points_and_radius( start, end, object_radius) starting_location_for_sample = placement.create_starting_location( position=start, routing_surface=self._routing_surface) water_constraint = self.get_water_constraint( self.fgl_parameters.min_water_depth, self.fgl_parameters.max_water_depth) fgl_context = placement.FindGoodLocationContext( starting_location_for_sample, object_polygons=(polygon, ), ignored_object_ids=[routing_agent.id, self._context.sim.sim_id], max_distance=0, min_water_depth=water_constraint.get_min_water_depth(), max_water_depth=water_constraint.get_max_water_depth()) (_, orientation) = placement.find_good_location(fgl_context) if orientation is None: return final_orientation = sims4.math.Quaternion.concatenate( orientation, initial_orientation) oriented_line_offset = final_orientation.transform_vector( line_length_offset) waypoint_constraints = [] for waypoint_index in range(0, waypoint_count): percent_down_line = waypoint_index / (waypoint_count - 1) goal_positon = oriented_line_offset * percent_down_line + start geometry = sims4.geometry.RestrictedPolygon( sims4.geometry.CompoundPolygon( sims4.geometry.Polygon((goal_positon, ))), ()) constraint = SmallAreaConstraint( geometry=geometry, routing_surface=self._routing_surface, min_water_depth=water_constraint.get_min_water_depth(), max_water_depth=water_constraint.get_max_water_depth()) waypoint_constraints.append(constraint) end = oriented_line_offset + start polygon = build_rectangle_from_two_points_and_radius( start, end, object_radius) self._footprint = PolygonFootprint( polygon, routing_surface=self._routing_surface, cost=routing.get_default_discouragement_cost(), footprint_type=FootprintType.FOOTPRINT_TYPE_OBJECT, enabled=True) routing_agent.routing_component.pathplan_context.ignore_footprint_contour( self._footprint.footprint_id) yield from waypoint_constraints
def try_to_place_bassinet(position, **kwargs): fgl_context = placement.FindGoodLocationContext( starting_position=position, object_id=sim_info.sim_id, search_flags=placement.FGLSearchFlagsDefault | placement.FGLSearchFlag.SHOULD_TEST_BUILDBUY, object_footprints=(bassinet.get_footprint(), ), **kwargs) (translation, orientation) = placement.find_good_location(fgl_context) if translation is not None and orientation is not None: bassinet.move_to(translation=translation, orientation=orientation) return True return False
def create_multiple_objects(number, *obj_ids, _connection=None): manager = services.object_manager() sim = get_optional_target(None, _connection) search_flags = placement.FGLSearchFlagsDefault | placement.FGLSearchFlag.SHOULD_TEST_BUILDBUY if sim is not None: starting_position = sim.position routing_surface = sim.routing_surface else: lot = services.active_lot() starting_position = lot.position routing_surface = routing.SurfaceIdentifier(services.current_zone().id, 0, routing.SURFACETYPE_WORLD) with postures.posture_graph.supress_posture_graph_build(): for obj_id in obj_ids: obj_id = int(obj_id) original_obj = None if obj_id in manager: original_obj = manager.get(obj_id) if original_obj is None: return obj_definition_id = original_obj.definition.id created_obj_count = number while created_obj_count > 0: if original_obj.crafting_component is not None: obj = DebugCreateCraftableInteraction.create_craftable( original_obj.crafting_component._crafting_process. recipe, sim) else: obj = objects.system.create_object(obj_definition_id) if obj is not None: fgl_context = placement.FindGoodLocationContext( starting_position=starting_position, object_id=obj.id, search_flags=search_flags, object_footprints=(obj.get_footprint(), )) (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, routing_surface=routing_surface) else: obj.destroy( source=obj, cause= 'Failed to find good location for create_multiple_objects' ) created_obj_count -= 1
def find_good_location(location): search_flags = placement.FGLSearchFlagsDefault | placement.FGLSearchFlag.USE_SIM_FOOTPRINT | placement.FGLSearchFlag.SHOULD_TEST_ROUTING starting_location = placement.create_starting_location( location=location) fgl_context = placement.FindGoodLocationContext( starting_location, additional_avoid_sim_radius=routing. get_sim_extra_clearance_distance(), search_flags=search_flags) (trans, _) = placement.find_good_location(fgl_context) if trans is None: return location new_transform = TurboMathUtil.Position.get_transform( trans, TurboMathUtil.Orientation.get_quaternion_identity()) return location.clone(transform=new_transform)
def _get_pos(self): participant = self._get_participant() trans = None if participant is not None: scoring_function = placement.ScoringFunctionRadial(participant.location.transform.translation, self._distance_to_participant, 0, FGLTuning.MAX_FGL_DISTANCE) search_flags = placement.FGLSearchFlag.STAY_IN_CONNECTED_CONNECTIVITY_GROUP | placement.FGLSearchFlag.USE_SIM_FOOTPRINT | placement.FGLSearchFlag.CALCULATE_RESULT_TERRAIN_HEIGHTS | placement.FGLSearchFlag.SHOULD_TEST_ROUTING starting_location = placement.create_starting_location(position=participant.position, orientation=participant.orientation, routing_surface=self.routing_surface) pos_increment_info = placement.PositionIncrementInfo(position_increment=self.POSITION_INCREMENT, from_exception=False) fgl_context = placement.FindGoodLocationContext(starting_location, max_distance=FGLTuning.MAX_FGL_DISTANCE, additional_avoid_sim_radius=routing.get_default_agent_radius(), max_steps=10, position_increment_info=pos_increment_info, offset_distance=self._distance_to_participant, scoring_functions=(scoring_function,), search_flags=search_flags) (trans, _) = placement.find_good_location(fgl_context) if trans is None: fallback_point = services.current_zone().get_spawn_point(lot_id=self.lot_id) (trans, _) = fallback_point.next_spawn_spot() self._routing_surface_override = fallback_point.routing_surface return trans return trans
def debug_create_baby(actor_sim, position, gender, routing_surface=None): baby = None try: actor_sim_info = actor_sim.sim_info account = actor_sim.sim_info.account sim_creator = SimCreator( gender=gender, age=Age.BABY, first_name=SimSpawner.get_random_first_name( account, gender == Gender.FEMALE), last_name=SimSpawner.get_family_name_for_gender( account, actor_sim.last_name, gender == Gender.FEMALE)) (sim_info_list, _) = SimSpawner.create_sim_infos( (sim_creator, ), household=actor_sim_info.household, account=account, zone_id=actor_sim_info.zone_id, creation_source='cheat: debug_create_baby') sim_info = sim_info_list[0] baby_def = Baby.get_default_baby_def() baby = create_object(baby_def, sim_info.sim_id) baby.set_sim_info(sim_info) fgl_context = placement.FindGoodLocationContext( starting_position=position, object_id=baby.id, search_flags=placement.FGLSearchFlagsDefault, object_footprints=(baby.get_footprint(), )) (trans, orient) = placement.find_good_location(fgl_context) if trans is not None: baby.location = sims4.math.Location( sims4.math.Transform(trans, orient), routing_surface) client = services.client_manager().get_client_by_household_id( sim_info.household_id) while client is not None: client.selectable_sims.add_selectable_sim_info(sim_info) except Exception as e: logger.exception('Create baby fail', e) if actor_sim_info.household.sim_in_household(sim_info.sim_id): actor_sim_info.household.remove_sim_info(sim_info) client = services.client_manager().get_client_by_household_id( sim_info.household_id) if client is not None: client.selectable_sims.remove_selectable_sim_info(sim_info) while baby is not None: baby.destroy(source=actor_sim, cause='Create baby fail')
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 fgl_context = placement.FindGoodLocationContext( starting_position=target.position + target.forward * radius_target.object_radius, starting_orientation=sims4.random.random_orientation(), starting_routing_surface=target.routing_surface, object_id=self.id, ignored_object_ids=ids_to_ignore, max_distance=max_distance, search_flags=flags) (position, orientation) = placement.find_good_location(fgl_context) if position is not None: destroy_puddle = False self.location = sims4.math.Location( sims4.math.Transform(position, orientation), target.routing_surface) self.fade_in() self.start_evaporation() return True return False finally: if destroy_puddle: self.destroy(source=self, cause='Failed to place puddle.')
def gsi_create_object(def_id, x_pos: float = None, y_pos: float = None, z_pos: float = None, _connection=None): obj = objects.system.create_object(def_id) if x_pos is None or y_pos is None or z_pos is None: start_pos = services.current_zone().lot.center else: start_pos = sims4.math.Vector3(x_pos, y_pos, z_pos) if obj is not None: search_flags = placement.FGLSearchFlagsDefault fgl_context = placement.FindGoodLocationContext( starting_position=start_pos, object_id=obj.id, max_distance=100, search_flags=search_flags, object_footprints=(obj.get_footprint(), )) (position, orientation) = placement.find_good_location(fgl_context) obj.transform = sims4.math.Transform(position, orientation) return True return False
def get_fgl_context_for_jig_definition(jig_definition, sim, target_sim=None, ignore_sim=True, max_dist=None, height_tolerance=None): max_facing_angle_diff = sims4.math.PI*2 if max_dist is None: max_dist = FGLTuning.MAX_FGL_DISTANCE if target_sim is None: relative_sim = sim if ignore_sim: ignored_object_ids = (sim.id,) else: ignored_object_ids = None reference_transform = sim.intended_transform else: relative_sim = target_sim ignored_object_ids = (sim.id, target_sim.id) reference_transform = target_sim.intended_transform additional_interaction_jig_fgl_distance = relative_sim.posture_state.body.additional_interaction_jig_fgl_distance starting_position = relative_sim.intended_position if additional_interaction_jig_fgl_distance != 0: starting_position += relative_sim.intended_forward*additional_interaction_jig_fgl_distance starting_location = routing.Location(starting_position, relative_sim.intended_transform.orientation, relative_sim.intended_routing_surface) facing_angle = sims4.math.yaw_quaternion_to_angle(reference_transform.orientation) fgl_context = placement.FindGoodLocationContext(starting_location=starting_location, routing_context=sim.routing_context, ignored_object_ids=ignored_object_ids, max_distance=max_dist, height_tolerance=height_tolerance, restrictions=(sims4.geometry.AbsoluteOrientationRange(min_angle=facing_angle - max_facing_angle_diff, max_angle=facing_angle + max_facing_angle_diff, ideal_angle=facing_angle, weight=1.0),), offset_restrictions=(sims4.geometry.RelativeFacingRange(reference_transform.translation, max_facing_angle_diff*2),), scoring_functions=(placement.ScoringFunctionRadial(reference_transform.translation, 0, 0, max_dist),), object_footprints=(jig_definition.get_footprint(0),), max_results=1, max_steps=10, search_flags=placement.FGLSearchFlag.STAY_IN_CONNECTED_CONNECTIVITY_GROUP | placement.FGLSearchFlag.SHOULD_TEST_ROUTING | placement.FGLSearchFlag.ALLOW_TOO_CLOSE_TO_OBSTACLE | placement.FGLSearchFlag.CALCULATE_RESULT_TERRAIN_HEIGHTS) return fgl_context
def teleport(self): if random.random() > self.chance_to_teleport: return if self.required_states is not None: for state in self.required_states: while 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: pass while obj.commodity_flags & motives: search_flags = placement.FGLSearchFlagsDefault | placement.FGLSearchFlag.SHOULD_TEST_BUILDBUY fgl_context = placement.FindGoodLocationContext( starting_position=obj.position, object_id=self.owner.id, search_flags=search_flags, object_footprints=(self.owner.get_footprint(), )) (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
def _test_safe_to_fish(self): safe = True if self.owner.is_in_inventory( ) or self.owner.parent_type != ObjectParentType.PARENT_NONE or self.owner.location.routing_surface is None: safe = False elif self._moving: safe = self._safe_to_fish_test.safe_while_moving elif self._safe_to_fish_test.constraints is not None: sim = self.owner if self.owner.is_sim else None ignored_object_ids = [self.owner.id] if sim is None: if self.owner.vehicle_component: for child in self.owner.children: if child.is_sim: sim = child ignored_object_ids.append(child.id) break constraint_total = ANYWHERE for constraint_factory in self._safe_to_fish_test.constraints: constraint = constraint_factory.create_constraint( sim, sim, target_position=self.owner.location.transform.translation, target_forward=self.owner.location.transform. transform_vector(sims4.math.FORWARD_AXIS), routing_surface=self.owner.location.routing_surface) constraint_total = constraint_total.intersect(constraint) if constraint_total.valid and constraint_total.geometry is not None: start_location = routing.Location( self.owner.location.transform.translation, self.owner.location.transform.orientation, self.owner.location.routing_surface) polygons = [constraint_total.geometry] def find_polygon_to_convert(): for polygon in polygons: if not isinstance(polygon, sims4.geometry.Polygon): return polygon polygon = find_polygon_to_convert() while polygon is not None: if isinstance(polygon, sims4.geometry.RestrictedPolygon): polygons.extend(polygon.polygon) elif isinstance(polygon, sims4.geometry.CompoundPolygon): polygons.extend(polygon) polygons.remove(polygon) polygon = find_polygon_to_convert() facing_angle = sims4.math.yaw_quaternion_to_angle( self.owner.location.transform.orientation) interval = sims4.geometry.interval_from_facing_angle( facing_angle, 0) abs_facing_range = sims4.geometry.AbsoluteOrientationRange( interval) fgl_context = placement.FindGoodLocationContext( start_location, object_polygons=polygons, restrictions=(abs_facing_range, ), ignored_object_ids=ignored_object_ids, max_distance=0, terrain_tags=constraint_total.get_terrain_tags(), min_water_depth=constraint_total.get_min_water_depth(), max_water_depth=constraint_total.get_max_water_depth()) (position, orientation) = placement.find_good_location(fgl_context) safe = position is not None and ( orientation is not None and (vector3_almost_equal(start_location.position, position) and quaternion_almost_equal(start_location.orientation, orientation))) else: logger.warning( 'Safe to Fish Test Constraint did not describe anything testable for {}' .format(self.owner)) if safe: for state_value in self._safe_to_fish_test.safe_states: self.owner.state_component.set_state(state_value.state, state_value) else: for state_value in self._safe_to_fish_test.unsafe_states: self.owner.state_component.set_state(state_value.state, state_value)
def _place_object_no_fallback(self, created_object): participant = self.interaction.get_participant( self.location.location_target) if self.location.location == self.POSITION: offset_tuning = self.location.offset_tuning 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, participant.transform).translation routing_surface = participant.routing_surface active_lot = services.active_lot() search_flags = placement.FGLSearchFlagsDefault if self.location.allow_off_lot_placement and not active_lot.is_position_on_lot( start_position): created_object.location = sims4.math.Location( sims4.math.Transform(start_position, start_orientation), routing_surface) polygon = placement.get_accurate_placement_footprint_polygon( created_object.position, created_object.orientation, created_object.scale, created_object.get_footprint()) context = placement.FindGoodLocationContext( starting_position=start_position, starting_orientation=start_orientation, starting_routing_surface=routing_surface, ignored_object_ids=(created_object.id, ), search_flags=search_flags, object_polygons=(polygon, )) else: if not self.location.ignore_bb_footprints: search_flags |= placement.FGLSearchFlag.SHOULD_TEST_BUILDBUY | placement.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) context = placement.FindGoodLocationContext( starting_position=start_position, starting_orientation=start_orientation, starting_routing_surface=routing_surface, object_id=created_object.id, ignored_object_ids=self._get_ignored_object_ids(), search_flags=search_flags, object_footprints=(self.definition.get_footprint(0), )) (translation, orientation) = placement.find_good_location(context) if translation is not None: created_object.move_to(routing_surface=routing_surface, translation=translation, orientation=orientation) return True elif self.location.location == self.SLOT: parent_slot = self.location.parent_slot if participant.slot_object(parent_slot=parent_slot, slotting_object=created_object): return True return False
def create_object_on_ground(self, source_object, spawner_data, max_distance, force_initialization_spawn): spawn_list = list(spawner_data.object_reference) parent_loc_type = self._get_inherited_spawn_location_type() for obj in spawn_list: if not services.lot_spawner_service_instance( ).check_spawner_firemeter(): logger.info( 'SpawnerComponent: Firemeter reached, object {} will not spawn', obj) return 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='camilogarcia') return created_obj.opacity = 0 if self.owner.is_on_active_lot(): search_flags = placement.FGLSearchFlagsDefault | FGLSearchFlag.SHOULD_TEST_BUILDBUY fgl_context = placement.FindGoodLocationContext( starting_position=created_obj.position, max_distance=max_distance, search_flags=search_flags, object_id=created_obj.id, height_tolerance=GlobalObjectSpawnerTuning. SPAWN_ON_GROUND_FGL_HEIGHT_TOLERANCE, object_footprints=( created_obj.definition.get_footprint(0), )) else: search_flags = placement.FGLSearchFlagsDefault created_obj.location = sims4.math.Location( sims4.math.Transform(self.owner.position, self.owner.orientation), self.owner.routing_surface) polygon = placement.get_accurate_placement_footprint_polygon( created_obj.position, created_obj.orientation, created_obj.scale, created_obj.get_footprint()) fgl_context = placement.FindGoodLocationContext( starting_position=created_obj.position, max_distance=max_distance, search_flags=search_flags, object_polygons=(polygon, ), height_tolerance=GlobalObjectSpawnerTuning. SPAWN_ON_GROUND_FGL_HEIGHT_TOLERANCE, ignored_object_ids=(self.owner.id, )) (position, orientation) = placement.find_good_location(fgl_context) if position is not None: created_obj.location = sims4.math.Location( sims4.math.Transform(position, orientation), source_object.routing_surface) services.lot_spawner_service_instance( ).register_spawned_object(created_obj) if force_initialization_spawn: force_states = spawner_data.spawner_option.force_initialization_spawn else: force_states = spawner_data.spawner_option.force_states 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 {}', created_obj, self.owner) created_obj.destroy( source=self.owner, cause='SpawnerComponent: FGL failed, object will not spawn.' )