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
def _compute_locations_for_posture(self): return (routing.Location( self.position + self.forward * self.LOCATION_OFFSET, self.orientation, self.routing_surface), routing.Location( self.position - self.forward * self.LOCATION_OFFSET, self.orientation, self.routing_surface))
def validate_spawn_points(self): if not self._spawner_data and not self._dynamic_spawn_points: return dest_handles = set() lot_center = self.lot.center lot_corners = self.lot.corners routing_surface = routing.SurfaceIdentifier(self.id, 0, routing.SURFACETYPE_WORLD) for corner in lot_corners: diff = lot_center - corner if diff.magnitude_squared() != 0: towards_center_vec = sims4.math.vector_normalize(lot_center - corner) * 0.1 else: towards_center_vec = sims4.math.Vector3.ZERO() new_corner = corner + towards_center_vec location = routing.Location( new_corner, sims4.math.Quaternion.IDENTITY(), routing_surface) dest_handles.add(routing.connectivity.Handle(location)) for spawn_point in self.spawn_points_gen(): spawn_point.reset_valid_slots() routing_context = routing.PathPlanContext() routing_context.set_key_mask(routing.FOOTPRINT_KEY_ON_LOT | routing.FOOTPRINT_KEY_OFF_LOT) if spawn_point.footprint_id is not None: routing_context.ignore_footprint_contour( spawn_point.footprint_id) spawn_point.validate_slots(dest_handles, routing_context)
def _do_route_gen(timeline): location = routing.Location(Vector3(x, y, z), routing_surface=obj.routing_surface) goal = routing.Goal(location) routing_context = obj.get_routing_context() route = routing.Route(obj.routing_location, (goal, ), routing_context=routing_context) plan_primitive = PlanRoute(route, obj) result = yield from element_utils.run_child(timeline, plan_primitive) if not result: return result yield nodes = plan_primitive.path.nodes if not (nodes and nodes.plan_success): return False yield else: follow_path_element = FollowPath(obj, plan_primitive.path) result = yield from element_utils.run_child( timeline, follow_path_element) if not result: return result yield return True yield
def _get_waypoint_constraints_from_polygons(self, polygons, object_constraints, waypoint_count): object_constraints = dict(object_constraints) total_area = sum(p.area() for (p, _) in itertools.chain.from_iterable(polygons.values())) sim_location = self._sim.routing_location sim_routing_context = self._sim.get_routing_context() restriction = None if self.object_tag_generator is not None: restriction = self.object_tag_generator.placement_restriction final_constraints = [] for (block_id, block_data) in polygons.items(): block_object_constraints = object_constraints.pop(block_id, ()) if restriction is not None: if restriction and block_id == 0: continue else: for (polygon, routing_surface) in block_data: polygon_waypoint_count = math.ceil(waypoint_count*(polygon.area()/total_area)) for position in random_uniform_points_in_compound_polygon(polygon, num=int(polygon_waypoint_count)): if not routing.test_connectivity_pt_pt(sim_location, routing.Location(position, routing_surface=self._routing_surface), sim_routing_context, ignore_objects=self._sim): continue position_constraint = Circle(position, self.constraint_radius, routing_surface=routing_surface) for block_object_constraint in tuple(block_object_constraints): intersection = block_object_constraint.intersect(position_constraint) if intersection.valid: block_object_constraints.remove(block_object_constraint) final_constraints.append(position_constraint) final_constraints.extend(block_object_constraints) final_constraints.extend(itertools.chain.from_iterable(object_constraints.values())) return final_constraints
def routing_location(self): lot = services.active_lot() return routing.Location(lot.position, orientation=lot.orientation, routing_surface=routing.SurfaceIdentifier( services.current_zone().id, 0, routing.SurfaceType.SURFACETYPE_WORLD))
def portal_setup(self): super().portal_setup() self.portal_cleanup() if not self._is_valid(): self._was_valid = False return self._was_valid = True pos = self.transform.translation (p0, p1, cross) = self._get_positions() door_routing_surface = self.routing_surface self.front_pos = p0 self.back_pos = p1 there = self.create_portal(routing.Location(p0 + cross, routing_surface=door_routing_surface), routing.Location(p1 + cross, routing_surface=door_routing_surface), Portal.PortalType.PortalType_Walk, self.id) back = self.create_portal(routing.Location(p1 - cross, routing_surface=door_routing_surface), routing.Location(p0 - cross, routing_surface=door_routing_surface), Portal.PortalType.PortalType_Walk, self.id) self.add_pair(there, back) self._footprints.append(self._build_discouragement_footprint(pos, p1, door_routing_surface, 1.0)) self._footprints.append(self._build_discouragement_footprint(pos, p1, door_routing_surface, -1.0))
def __init__(self, obj, position): super().__init__( routing.Location(position, orientation=obj.orientation, routing_surface=obj.routing_surface), obj.routing_surface) self.obj = obj self.assigned = False
def _test(cls, target, context, **kwargs): if context.pick is None: return TestResult(False, 'Pool edge social has no picked location.') position = context.pick.location surface = context.pick.routing_surface routing_location = routing.Location(position, sims4.math.Quaternion.IDENTITY(), surface) if not routing.test_connectivity_permissions_for_handle(routing.connectivity.Handle(routing_location), context.sim.routing_context): return TestResult(False, 'Cannot build constraint over an unroutable area.') return super()._test(target, context, **kwargs)
def portal_setup(self): super().portal_setup() stair_lanes = routing.get_stair_portals(self.id, self.zone_id) self._cached_lanes = stair_lanes for lane in stair_lanes: created_portals = [] for end_set in lane: lane_start = end_set[0] lane_end = end_set[1] start_pos = lane_start[0] end_pos = lane_end[0] diff = start_pos - end_pos traversal_cost = diff.magnitude() * 4.0 created_portals.append( self.create_portal( routing.Location(start_pos, routing_surface=lane_start[1]), routing.Location(end_pos, routing_surface=lane_end[1]), Portal.PortalType.PortalType_Animate, self.id, traversal_cost)) self.add_pair(*created_portals)
def is_terrain_location_valid(cls, interaction_target, interaction_context): (position, surface) = cls._get_position_and_surface(interaction_target, interaction_context) if position is None: return False if interaction_context.pick is not None and (interaction_context.pick.pick_type is not None and (interaction_context.pick.pick_type != PickType.PICK_TERRAIN and interaction_context.pick.pick_type != PickType.PICK_FLOOR)) and interaction_context.pick.pick_type != PickType.PICK_POOL_SURFACE: return False if surface is None: return False routing_location = routing.Location(position, TurboMathUtil.Orientation.get_quaternion_identity(), surface) if not routing.test_connectivity_permissions_for_handle(routing.connectivity.Handle(routing_location), interaction_context.sim.routing_context): return False return True
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)
def _test(cls, target, context, **kwargs): (position, surface) = cls._get_position_and_surface(target, context) if position is None or surface is None: return TestResult(False, 'Cannot go here without a pick or target.') location = routing.Location(position, sims4.math.Quaternion.IDENTITY(), surface) if not routing.test_connectivity_permissions_for_handle( routing.connectivity.Handle(location), context.sim.routing_context): return TestResult(False, 'Cannot TeleportHere! Unroutable area.') return TestResult.TRUE
def _get_offset_positions(self, there_entry, there_exit, angle): if self.bidirectional_portal_offset is not None and there_entry.routing_surface.type == SurfaceType.SURFACETYPE_OBJECT: entry_exit = there_exit.position - there_entry.position unit_vector = sims4.math.vector_normalize(entry_exit) modified_position = Vector3( there_entry.position.x + unit_vector.x * self.bidirectional_portal_offset, there_entry.position.y, there_entry.position.z + unit_vector.z * self.bidirectional_portal_offset) return routing.Location( modified_position, sims4.math.angle_to_yaw_quaternion(angle), routing_surface=there_entry.routing_surface) return there_entry
def __init__(self, guid, template=None, debug_name=None, parent=None, species=None): self.id = guid self.template = template if species is not None: self._species = species elif template is not None: self._species = template.species else: self._species = Species.HUMAN self.debug_name = debug_name self.parent = parent self.asm_auto_exit = AsmAutoExitInfo() self.routing_context = PathPlanContext() zone_id = services.current_zone_id() routing_surface = routing.SurfaceIdentifier(zone_id or 0, 0, routing.SurfaceType.SURFACETYPE_WORLD) self.routing_location = routing.Location(sims4.math.Vector3.ZERO(), sims4.math.Quaternion.IDENTITY(), routing_surface)
def _test(cls, target, context, **kwargs): (position, surface) = cls._get_position_and_surface(target, context) if position is None: return TestResult(False, 'Cannot go here without a pick or target.') if context.pick is not None and context.pick.pick_type == PickType.PICK_POOL_EDGE: return TestResult.TRUE plex_service = services.get_plex_service() if plex_service.is_active_zone_a_plex(): plex_zone_id_at_pick = plex_service.get_plex_zone_at_position( position, surface.secondary_id) if plex_zone_id_at_pick is not None and plex_zone_id_at_pick != services.current_zone_id( ): return TestResult(False, 'Pick point in inactive plex') routing_location = routing.Location(position, sims4.math.Quaternion.IDENTITY(), surface) routing_context = context.sim.get_routing_context() objects_to_ignore = set() if target is not None and target.is_sim: posture_target = target.posture_target if posture_target is not None: objects_to_ignore.update( posture_target.parenting_hierarchy_gen()) if context.sim is not None: posture_target = context.sim.posture_target if posture_target.vehicle_component is not None: posture_target = posture_target.part_owner if posture_target.is_part else posture_target objects_to_ignore.add(posture_target) try: for obj in objects_to_ignore: footprint_component = obj.footprint_component if footprint_component is not None: routing_context.ignore_footprint_contour( footprint_component.get_footprint_id()) if not routing.test_connectivity_permissions_for_handle( routing.connectivity.Handle(routing_location), routing_context): return TestResult(False, 'Cannot GoHere! Unroutable area.') finally: for obj in objects_to_ignore: footprint_component = obj.footprint_component if footprint_component is not None: routing_context.remove_footprint_contour_override( footprint_component.get_footprint_id()) return TestResult.TRUE
def validate_slots(self, dest_handles, routing_context): src_handles_to_indices = {} for index in range(WorldSpawnPoint.SPAWN_POINT_SLOTS): slot_pos = self.get_slot_pos(index) location = routing.Location(slot_pos, sims4.math.Quaternion.IDENTITY(), self.routing_surface) src_handles_to_indices[routing.connectivity.Handle( location)] = index connectivity = routing.test_connectivity_batch( set(src_handles_to_indices.keys()), dest_handles, routing_context=routing_context, flush_planner=True) if connectivity is not None: for (src, _, _) in connectivity: index = src_handles_to_indices.get(src) while index is not None: self._valid_slots = self._valid_slots | 1 << index
def run_away(self, pet_info): if self.missing_pet_id != 0 or self._running_away: return if not self._household.is_active_household or self._household.home_zone_id != services.current_zone_id(): return if self._cooldown_alarm is not None: return pet = pet_info.get_sim_instance() if pet is None: return spawn_point = services.current_zone().get_spawn_point(lot_id=services.active_lot_id()) routing_location = routing.Location(spawn_point.get_approximate_center(), sims4.math.Quaternion.ZERO(), spawn_point.routing_surface) if not routing.test_connectivity_pt_pt(pet.routing_location, routing_location, pet.routing_context): return if self._push_run_away_affordance(pet): if self.RUN_AWAY_NOTIFICATION is not None: dialog = self.RUN_AWAY_NOTIFICATION(pet_info, SingleSimResolver(pet_info)) dialog.show_dialog() self._running_away = True
def get_routes_gen(self): if self._target is None: return False yield slave_data = self._target.get_formation_data_for_slave(self._obj) if slave_data is None: return False yield starting_location = self._target.intended_location transform = slave_data.find_good_location_for_slave(starting_location) if transform is None: return False yield goal = Goal( routing.Location(transform.translation, transform.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
def travel_pick_info_test(cls, target, context, **kwargs): (position, surface, result) = cls._get_target_position_surface_and_test_off_lot( target, context) if not result: return result location = routing.Location(position, sims4.math.Quaternion.IDENTITY(), surface) routable = routing.test_connectivity_permissions_for_handle( routing.connectivity.Handle(location), context.sim.routing_context) if routable: return TestResult(False, 'Cannot Travel from routable terrain !') result = cls.travel_test(context) if not result: return result to_zone_id = context.pick.get_zone_id_from_pick_location() if to_zone_id is None: return TestResult( False, 'Could not resolve lot id: {} into a valid zone id.', context.pick.lot_id) return TestResult.TRUE
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 _fall_to_ground(self): self._cancel_fall_to_ground_retry_alarm() if not self.is_on_tree: return if self.owner.in_use: self._fall_to_ground_retry_alarm_handle = alarms.add_alarm( self.owner, TimeSpan.in_real_world_seconds(10), self._fall_to_ground) return parent_obj = self.owner.parent if parent_obj is None: logger.warn('{}: Fruit failed to fall, it is no longer parented.', self.owner) return target_location = routing.Location( self.owner.routing_location.position, parent_obj.routing_location.orientation, parent_obj.routing_location.routing_surface) context = FindGoodLocationContext( starting_routing_location=target_location, object_footprints=(self.plant.get_footprint(0), ), max_distance=self.fruit_fall_behavior.search_radius.upper_bound) (translation, orientation) = find_good_location(context) if translation is None or orientation is None: logger.warn('{}: Failed to fall because FGL failed.', self.owner) self.owner.destroy(source=parent_obj, cause='Failed to fall because FGL failed') return if self.owner.parent is not None: self.owner.clear_parent( sims4.math.Transform(translation, orientation), self.owner.routing_surface) else: self.owner.set_location( sims4.math.Location( sims4.math.Transform(translation, orientation), self.owner.routing_surface))
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
def validate_connectivity(self, dest_handles): self._valid_slots = 0 src_handles_to_indices = {} for index in range(WorldSpawnPoint.SPAWN_POINT_SLOTS): slot_pos = self._get_slot_pos(index) location = routing.Location(slot_pos, sims4.math.Quaternion.IDENTITY(), self.routing_surface) src_handles_to_indices[routing.connectivity.Handle( location)] = index routing_context = routing.PathPlanContext() routing_context.set_key_mask(routing.FOOTPRINT_KEY_ON_LOT | routing.FOOTPRINT_KEY_OFF_LOT) routing_context.ignore_footprint_contour(self._footprint_id) connectivity = routing.test_connectivity_batch( set(src_handles_to_indices.keys()), dest_handles, routing_context=routing_context, flush_planner=True) if connectivity is not None: for (src, _, _) in connectivity: index = src_handles_to_indices.get(src) if index is not None: self._valid_slots = self._valid_slots | 1 << index
def get_routing_location_for_transform(self, transform, routing_surface=DEFAULT): routing_surface = self.routing_surface if routing_surface is DEFAULT else routing_surface return routing.Location(transform.translation, transform.orientation, routing_surface)
def _create_constraint_set(self, sim, timeline): orient = sims4.math.Quaternion.IDENTITY() positions = services.current_zone().lot.corners position = positions[0] routing_surface = self._privacy.constraint.get_world_routing_surface( force_world=True) if self._privacy._routing_surface_only: routing_surfaces = (routing_surface, ) else: routing_surfaces = self._privacy.constraint.get_all_valid_routing_surfaces( ) goals = [] center_pos = services.current_zone().lot.position for pos in positions: plex_service = services.get_plex_service() if plex_service.is_active_zone_a_plex(): towards_center_vec = sims4.math.vector_normalize(center_pos - pos) pos = pos + towards_center_vec * self.PLEX_LOT_CORNER_ADJUSTMENT pos.y = services.terrain_service.terrain_object( ).get_routing_surface_height_at(pos.x, pos.z, routing_surface) if not sims4.geometry.test_point_in_compound_polygon( pos, self._privacy.constraint.geometry.polygon): for surface in routing_surfaces: goals.append( routing.Goal(routing.Location(pos, orient, surface))) obj_pos = self._privacy.central_object.position for offset in self._privacy.additional_exit_offsets: goals.append( routing.Goal( routing.Location(obj_pos + Vector3(offset.x, 0, offset.y), orient, surface))) if not goals: return Nowhere( 'BuildAndForceSatisfyShooConstraintInteraction, Could not generate goals to exit a privacy region, Sim: {} Privacy Region: {}', sim, self._privacy.constraint.geometry.polygon) yield route = routing.Route(sim.routing_location, goals, routing_context=sim.routing_context) plan_primitive = PlanRoute(route, sim, reserve_final_location=False, interaction=self) yield from element_utils.run_child(timeline, plan_primitive) max_distance = self._privacy._max_line_of_sight_radius * self._privacy._max_line_of_sight_radius * 4 nodes = [] path = plan_primitive.path while path is not None: nodes.extend(path.nodes) path = path.next_path if nodes: previous_node = nodes[0] for node in nodes: node_vector = sims4.math.Vector3(node.position[0], node.position[1], node.position[2]) if not sims4.geometry.test_point_in_compound_polygon( node_vector, self._privacy.constraint.geometry.polygon): position = node_vector if node.portal_id != 0: continue circle_constraint = interactions.constraints.Circle( position, self.TRIVIAL_SHOO_RADIUS, node.routing_surface_id) if circle_constraint.intersect( self._privacy.constraint).valid: continue break previous_node = node position2 = sims4.math.Vector3(previous_node.position[0], previous_node.position[1], previous_node.position[2]) if (position - position2).magnitude_2d_squared() > max_distance: position = self._find_close_position(position, position2) elif (position - sim.position).magnitude_2d_squared() > max_distance: position = self._find_close_position(position, sim.position) p1 = position p2 = self._privacy.central_object.position forward = sims4.math.vector_normalize(p1 - p2) radius_min = 0 radius_max = self._privacy.shoo_constraint_radius angle = sims4.math.PI (cone_geometry, cost_functions) = build_weighted_cone(position, forward, radius_min, radius_max, angle, ideal_radius_min=0, ideal_radius_max=0, ideal_angle=1) subtracted_cone_polygon_list = [] for cone_polygon in cone_geometry.polygon: for privacy_polygon in self._privacy.constraint.geometry.polygon: subtracted_cone_polygons = cone_polygon.subtract( privacy_polygon) if subtracted_cone_polygons: subtracted_cone_polygon_list.extend( subtracted_cone_polygons) compound_subtracted_cone_polygon = sims4.geometry.CompoundPolygon( subtracted_cone_polygon_list) subtracted_cone_geometry = sims4.geometry.RestrictedPolygon( compound_subtracted_cone_polygon, []) subtracted_cone_constraint = Constraint( geometry=subtracted_cone_geometry, scoring_functions=cost_functions, routing_surface=routing_surface, debug_name='ShooedSimsCone', multi_surface=True, los_reference_point=position) point_cost = 5 point_constraint = interactions.constraints.Position( position, routing_surface=routing_surface, multi_surface=True) point_constraint = point_constraint.generate_constraint_with_cost( point_cost) constraints = (subtracted_cone_constraint, point_constraint) return interactions.constraints.create_constraint_set( constraints, debug_name='ShooPositions') yield
def get_routing_location_for_transform(self, transform, **__): return routing.Location( transform.translation, transform.orientation, routing_surface=self.routing_location.routing_surface)
def prepare_gen(self, timeline, *args, **kwargs): if not self.sim.can_sim_teleport_using_teleport_style(): return InteractionQueuePreparationStatus.FAILURE yield try: (starting_position, routing_surface_id) = self._get_position_and_surface( self.target, self.context) desired_level = self._get_level_of_target(self.target, self.context) if starting_position is not None: if routing_surface_id is not None: if desired_level is not None: if self.required_destination_surface is not None: zone_id = services.current_zone_id() routing_surface_id = routing.SurfaceIdentifier( zone_id or 0, desired_level, self.required_destination_surface) starting_location = routing.Location( starting_position, routing_surface=routing_surface_id) if self.destination_jig is not None: self._destination_jig_object = self._create_jig_object( ) if self._destination_jig_object is not None: ( position, orientation ) = TeleportHelper.get_fgl_at_destination_for_teleport( starting_location, self._destination_jig_object, destination_must_be_outside=self. destination_must_be_outside) if position is not None: if orientation is not None: self._destination_jig_object.move_to( translation=position, orientation=orientation, routing_surface=routing_surface_id) object_slots = self.destination_jig.get_slots_resource( 0) jig_slot_transform = object_slots.get_slot_transform_by_index( sims4.ObjectSlots.SLOT_ROUTING, 0) jig_slot_concat_transform = sims4.math.Transform.concatenate( sims4.math.Transform( position, orientation), jig_slot_transform) self._teleport_location = routing.Location( jig_slot_concat_transform. translation, orientation=jig_slot_concat_transform .orientation, routing_surface=routing_surface_id) else: ( position, orientation ) = TeleportHelper.get_fgl_at_destination_for_teleport( starting_location, self.sim, destination_must_be_outside=self. destination_must_be_outside) if position is None: if services.current_zone( ).lot.is_position_on_lot(starting_position): front_door = services.get_door_service( ).get_front_door() if front_door: routing_surface_id = front_door.routing_surface door_location = routing.Location( front_door.position, routing_surface=routing_surface_id) ( position, orientation ) = TeleportHelper.get_fgl_at_destination_for_teleport( door_location, self.sim, destination_must_be_outside=self. destination_must_be_outside, ignore_connectivity=True) if position is not None: if orientation is not None: self._teleport_location = routing.Location( position, orientation=orientation, routing_surface=routing_surface_id) except Exception as exception: logger.exception( 'Exception while getting teleport location for TeleportStyleSuperInteraction: ', exc=exception, level=sims4.log.LEVEL_ERROR) self._try_destroy_jig_object() if self._teleport_location is None: return InteractionQueuePreparationStatus.FAILURE yield result = yield from super().prepare_gen(timeline, **kwargs) return result yield
def routing_location(self): return routing.Location( self._pick_location.transform.translation, orientation=self._pick_location.transform.orientation, routing_surface=self._pick_location.routing_surface)
def get_route_to_position_goals(position, routing_surface, orientation=None): goal_location = routing.Location(position, orientation, routing_surface) return [routing.Goal(goal_location)]