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 behavior_element(self, timeline): total_constraint = ANYWHERE for (relative_participant, constraints) in self.route_constraints.items(): relative_object = self.interaction.get_participant( relative_participant) if relative_object is None: continue for constraint in constraints: relative_constraint = constraint.create_constraint( self.interaction.sim, relative_object, objects_to_ignore=[relative_object]) total_constraint = total_constraint.intersect( relative_constraint) if not total_constraint.valid: logger.error( 'Routing Element cannot resolve constraints for {}', self.interaction) return False yield sim = self.interaction.sim goals = [] handles = total_constraint.get_connectivity_handles(sim) for handle in handles: goals.extend(handle.get_goals()) if not goals: return False yield route = routing.Route(sim.routing_location, goals, routing_context=sim.routing_context) plan_primitive = PlanRoute(route, sim, interaction=self.interaction) result = yield from element_utils.run_child(timeline, plan_primitive) if not result: return False yield if not (plan_primitive.path.nodes and plan_primitive.path.nodes.plan_success): return False yield route = get_route_element_for_path(sim, plan_primitive.path, interaction=self.interaction) result = yield from element_utils.run_child( timeline, build_critical_section(route)) return result yield
def get_routes_gen(self): if self._target is None: return False yield routing_slot_constraint = self.constraint.create_constraint( self._obj, self._target) goals = list( itertools.chain.from_iterable( h.get_goals() for h in routing_slot_constraint.get_connectivity_handles( self._obj))) routing_context = self._obj.get_routing_context() route = routing.Route(self._obj.routing_location, goals, routing_context=routing_context) yield route
def _do_route_to_constraint_gen(self, waypoints, timeline): if self.is_finishing: return False yield plan_primitives = [] for (i, routing_info) in enumerate(self._routing_infos): routing_agent = routing_info[0] routing_context = routing_info[1] route = routing.Route(routing_agent.routing_location, waypoints[-1], waypoints=waypoints[:-1], routing_context=routing_context) plan_primitive = PlanRoute(route, routing_agent, interaction=self) result = yield from element_utils.run_child(timeline, plan_primitive) if not result: self._show_route_fail_balloon() return False yield if not (plan_primitive.path.nodes and plan_primitive.path.nodes.plan_success): self._show_route_fail_balloon() return False yield plan_primitive.path.blended_orientation = self.waypoint_randomize_orientation plan_primitives.append(plan_primitive) if i == len(self._routing_infos) - 1: continue for node in plan_primitive.path.nodes: position = Vector3(*node.position) for goal in itertools.chain.from_iterable(waypoints): if goal.routing_surface_id != node.routing_surface_id: continue dist_sq = (Vector3(*goal.position) - position).magnitude_2d_squared() if dist_sq < self._goal_size: goal.cost = routing.get_default_obstacle_cost() route_primitives = [] track_override = None mask_override = None if self.waypoint_clear_locomotion_mask: mask_override = 0 track_override = 9999 for plan_primitive in plan_primitives: sequence = get_route_element_for_path(plan_primitive.sim, plan_primitive.path, interaction=self, force_follow_path=True, track_override=track_override, mask_override=mask_override) walkstyle_request = self.waypoint_walk_style(plan_primitive.sim) sequence = walkstyle_request(sequence=sequence) route_primitives.append(sequence) result = yield from element_utils.run_child(timeline, do_all(*route_primitives)) return result yield
def plan_fetch_paths(timeline): for target_sim in self.get_participants( ParticipantType.TargetSim | ParticipantType.Listeners): fetch_constraint = self.fetch_constraint.create_constraint( target_sim, target_position=self._distance_placement_transform. translation, routing_surface=self._routing_surface if self._routing_surface is not None else DEFAULT) facing = interactions.constraints.Facing( target_position=self._distance_placement_transform. translation, inner_radius=self.facing_radius) fetch_constraint = fetch_constraint.intersect(facing) if not fetch_constraint.valid: continue goals = [] handles = fetch_constraint.get_connectivity_handles(target_sim) for handle in handles: goals.extend(handle.get_goals()) if not goals: pass else: route = routing.Route( target_sim.routing_location, goals, routing_context=target_sim.routing_context) plan_primitive = PlanRoute(route, target_sim, interaction=self) result = yield from element_utils.run_child( timeline, plan_primitive) if result: if plan_primitive.path.nodes: if plan_primitive.path.nodes.plan_success: if plan_primitive.path.portal_obj is not None: logger.error( 'Need sub interaction to route {} due to portal on path' .format(target_sim)) else: self._plan_primitives.append( plan_primitive) yield from element_utils.run_child(timeline, sequence)
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 get_routes_gen(self): waypoint_generator = self.waypoint_generator( WaypointContext(self._obj), None) waypoints = [] constraints = itertools.chain( (waypoint_generator.get_start_constraint(), ), waypoint_generator.get_waypoint_constraints_gen( self._obj, self.waypoint_count)) obj_start_constraint = Circle( self._obj.position, self.return_to_starting_point, routing_surface=self._obj.routing_surface, los_reference_point=None) constraints = itertools.chain(constraints, obj_start_constraint) for constraint in constraints: goals = list( itertools.chain.from_iterable( h.get_goals() for h in constraint.get_connectivity_handles(self._obj))) if not goals: continue for goal in goals: goal.orientation = sims4.math.angle_to_yaw_quaternion( random.uniform(0.0, sims4.math.TWO_PI)) waypoints.append(goals) if not (self.return_to_starting_point is not None and waypoints): return False yield routing_context = self._obj.get_routing_context() for route_waypoints in self.waypoint_stitching( waypoints, waypoint_generator.loops): route = routing.Route(self._obj.routing_location, route_waypoints[-1], waypoints=route_waypoints[:-1], routing_context=routing_context) yield route return True yield
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 _do_route_gen(timeline): routing_context = obj.get_routing_context() route = routing.Route(obj.routing_location, waypoints[-1], waypoints=waypoints[:-1], 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 _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 generate_path(self, timeline): start_time = services.time_service().sim_now ticks = 0 try: self.path.status = routing.Path.PLANSTATUS_PLANNING self.path.nodes.clear_route_data() if not self.route.goals: self.path.status = routing.Path.PLANSTATUS_FAILED else: for goal in self.route.goals: self.path.add_goal(goal) for origin in self.route.origins: self.path.add_start(origin) self.sim.on_plan_path(self.route.goals, True) if self.path.nodes.make_path() is True: def is_planning_done(): nonlocal ticks ticks += 1 return not self.path.nodes.plan_in_progress yield element_utils.run_child(timeline, elements.BusyWaitElement(soft_sleep_forever(), is_planning_done)) self.path.nodes.finalize(self._is_failure_route) else: self.path.status = routing.Path.PLANSTATUS_FAILED new_route = routing.Route(self.route.origin, self.route.goals, additional_origins=self.route.origins, routing_context=self.route.context) new_route.path.copy(self.route.path) new_path = routing.Path(self.path.sim, new_route) new_path.status = self.path.status new_path._start_ids = self.path._start_ids new_path._goal_ids = self.path._goal_ids result_path = new_path if len(new_path.nodes) > 0: start_index = 0 current_index = 0 for n in self.path.nodes: if n.portal_object_id != 0: portal_object = services.object_manager(services.current_zone_id()).get(n.portal_object_id) if portal_object is not None and portal_object.split_path_on_portal(): new_path.nodes.clip_nodes(start_index, current_index) new_route = routing.Route(self.route.origin, self.route.goals, additional_origins=self.route.origins, routing_context=self.route.context) new_route.path.copy(self.route.path) next_path = routing.Path(self.path.sim, new_route) next_path.status = self.path.status next_path._start_ids = self.path._start_ids next_path._goal_ids = self.path._goal_ids new_path.next_path = next_path new_path.portal = portal_object new_path = next_path start_index = current_index + 1 current_index = current_index + 1 new_path.nodes.clip_nodes(start_index, current_index - 1) self.route = result_path.route self.path = result_path self.sim.on_plan_path(self.route.goals, False) except Exception: logger.exception('Exception in generate_path') self.path.status = routing.Path.PLANSTATUS_FAILED self.sim.on_plan_path(self.route.goals, False) if self.path.status == routing.Path.PLANSTATUS_PLANNING: self.path.set_status(routing.Path.PLANSTATUS_READY) else: self.path.set_status(routing.Path.PLANSTATUS_FAILED) if gsi_handlers.routing_handlers.archiver.enabled: gsi_handlers.routing_handlers.archive_plan(self.sim, self.path, ticks, (services.time_service().sim_now - start_time).in_real_world_seconds())
def _create_constraint_set(self, sim, timeline): orient = sims4.math.Quaternion.IDENTITY() positions = services.current_zone().lot.corners position = positions[0] goals = [] for pos in positions: while not sims4.geometry.test_point_in_compound_polygon( pos, self._privacy.constraint.geometry.polygon): goals.append( routing.Goal( routing.Location(pos, orient, sim.routing_surface))) if not goals: return Nowhere() route = routing.Route(sim.routing_location, goals, routing_context=sim.routing_context) plan_primitive = PlanRoute(route, sim, reserve_final_location=False) yield 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 = plan_primitive.path.nodes 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: pass circle_constraint = interactions.constraints.Circle( position, self.TRIVIAL_SHOO_RADIUS, node.routing_surface_id) if circle_constraint.intersect( self._privacy.constraint).valid: pass 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, scoring_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) while 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=scoring_functions, routing_surface=sim.routing_surface, debug_name='ShooedSimsCone', los_reference_point=position) point_cost = 5 point_constraint = interactions.constraints.Position( position, routing_surface=sim.routing_surface) 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')
def _get_close_to_deploy(self, timeline, vehicle): sim = self._interaction.sim constraint = self._get_deployment_constraint() if not constraint.valid: return InteractionQueuePreparationStatus.FAILURE yield handles = constraint.get_connectivity_handles(sim) goals = [] for handle in handles: goals.extend(handle.get_goals(single_goal_only=True)) if not goals: return InteractionQueuePreparationStatus.FAILURE yield if sim.posture.unconstrained: source_constraint = Position(sim.position, routing_surface=sim.routing_surface) else: source_constraint = Circle(sim.position, self.SOURCE_CONNECTIVITY_HANDLE_RADIUS, sim.routing_surface) source_handles = source_constraint.get_connectivity_handles(sim) if not source_handles: return InteractionQueuePreparationStatus.FAILURE yield source_goals = source_handles[0].get_goals(single_goal_only=True) if not source_goals: return InteractionQueuePreparationStatus.FAILURE yield source_goal = source_goals[0] if source_goal.position == goals[0].position and source_goal.routing_surface_id == goals[0].routing_surface_id: return InteractionQueuePreparationStatus.SUCCESS yield route = routing.Route(source_goal.location, goals, routing_context=sim.routing_context) plan_primitive = PlanRoute(route, sim, interaction=self._interaction) result = yield from element_utils.run_child(timeline, plan_primitive) if not result and not (not plan_primitive.path.nodes and not plan_primitive.path.nodes.plan_success): return InteractionQueuePreparationStatus.FAILURE yield cur_path = plan_primitive.path if not cur_path.nodes: return InteractionQueuePreparationStatus.FAILURE yield def get_start_node_index_for_path(vehicle, path): nodes = list(path.nodes) object_manager = services.object_manager() prev_node = None for node in nodes[::-1]: portal_obj_id = node.portal_object_id portal_obj = object_manager.get(portal_obj_id) if portal_obj_id else None if node.portal_id: if portal_obj: if not vehicle.vehicle_component.can_transition_through_portal(portal_obj, node.portal_id): break prev_node = node else: return 0 return prev_node.index split_paths = False while cur_path.next_path is not None: split_paths = True cur_path = cur_path.next_path if not cur_path.nodes: return InteractionQueuePreparationStatus.FAILURE yield start_node_index = get_start_node_index_for_path(vehicle, cur_path) start_node = cur_path.nodes[start_node_index] start_location = sims4.math.Location(Transform(Vector3(*start_node.position), Quaternion(*start_node.orientation)), start_node.routing_surface_id) if not split_paths and start_node_index == 0 and (start_location.transform.translation - source_goal.location.position).magnitude_squared() < vehicle.vehicle_component.minimum_route_distance: return InteractionQueuePreparationStatus.SUCCESS yield deploy_constraint = Position(start_location.transform.translation, routing_surface=start_location.routing_surface) depended_on_si = self._interaction affordance = self.get_close_affordance if self.get_close_affordance is not None else VehicleLiability.GET_CLOSE_AFFORDANCE aop = AffordanceObjectPair(affordance, None, affordance, None, route_fail_on_transition_fail=False, constraint_to_satisfy=deploy_constraint, allow_posture_changes=True, depended_on_si=depended_on_si) context = InteractionContext(sim, InteractionContext.SOURCE_SCRIPT, Priority.High, insert_strategy=QueueInsertStrategy.FIRST, must_run_next=True, group_id=depended_on_si.group_id) if not aop.test_and_execute(context): return InteractionQueuePreparationStatus.FAILURE yield return InteractionQueuePreparationStatus.NEEDS_DERAIL yield