Exemplo n.º 1
0
 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
Exemplo n.º 2
0
 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
Exemplo n.º 4
0
 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
Exemplo n.º 5
0
 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
Exemplo n.º 9
0
 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
Exemplo n.º 10
0
 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
Exemplo n.º 11
0
    def generate_path(self, timeline):
        start_time = services.time_service().sim_now
        ticks = 0
        try:
            self.path.status = routing.Path.PLANSTATUS_PLANNING
            self.path.nodes.clear_route_data()
            if not self.route.goals:
                self.path.status = routing.Path.PLANSTATUS_FAILED
            else:
                for goal in self.route.goals:
                    self.path.add_goal(goal)
                for origin in self.route.origins:
                    self.path.add_start(origin)
                self.sim.on_plan_path(self.route.goals, True)
                if self.path.nodes.make_path() is True:

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

                    yield element_utils.run_child(timeline, elements.BusyWaitElement(soft_sleep_forever(), is_planning_done))
                    self.path.nodes.finalize(self._is_failure_route)
                else:
                    self.path.status = routing.Path.PLANSTATUS_FAILED
                new_route = routing.Route(self.route.origin, self.route.goals, additional_origins=self.route.origins, routing_context=self.route.context)
                new_route.path.copy(self.route.path)
                new_path = routing.Path(self.path.sim, new_route)
                new_path.status = self.path.status
                new_path._start_ids = self.path._start_ids
                new_path._goal_ids = self.path._goal_ids
                result_path = new_path
                if len(new_path.nodes) > 0:
                    start_index = 0
                    current_index = 0
                    for n in self.path.nodes:
                        if n.portal_object_id != 0:
                            portal_object = services.object_manager(services.current_zone_id()).get(n.portal_object_id)
                            if portal_object is not None and portal_object.split_path_on_portal():
                                new_path.nodes.clip_nodes(start_index, current_index)
                                new_route = routing.Route(self.route.origin, self.route.goals, additional_origins=self.route.origins, routing_context=self.route.context)
                                new_route.path.copy(self.route.path)
                                next_path = routing.Path(self.path.sim, new_route)
                                next_path.status = self.path.status
                                next_path._start_ids = self.path._start_ids
                                next_path._goal_ids = self.path._goal_ids
                                new_path.next_path = next_path
                                new_path.portal = portal_object
                                new_path = next_path
                                start_index = current_index + 1
                        current_index = current_index + 1
                    new_path.nodes.clip_nodes(start_index, current_index - 1)
                self.route = result_path.route
                self.path = result_path
                self.sim.on_plan_path(self.route.goals, False)
        except Exception:
            logger.exception('Exception in generate_path')
            self.path.status = routing.Path.PLANSTATUS_FAILED
            self.sim.on_plan_path(self.route.goals, False)
        if self.path.status == routing.Path.PLANSTATUS_PLANNING:
            self.path.set_status(routing.Path.PLANSTATUS_READY)
        else:
            self.path.set_status(routing.Path.PLANSTATUS_FAILED)
        if gsi_handlers.routing_handlers.archiver.enabled:
            gsi_handlers.routing_handlers.archive_plan(self.sim, self.path, ticks, (services.time_service().sim_now - start_time).in_real_world_seconds())
 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')
Exemplo n.º 13
0
    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