Ejemplo n.º 1
0
    def on_zone_load(self):
        global _ocean_object
        if _ocean_object is None:
            beach_locator_def = OceanTuning.get_beach_locator_definition()
            if beach_locator_def is None:
                return
            locator_manager = services.locator_manager()
            locators = locator_manager.get(beach_locator_def.id)
            if not locators:
                return

            def move_ocean(ocean):
                zone = services.current_zone()
                terrain_center = zone.lot.center
                location = sims4.math.Location(
                    sims4.math.Transform(
                        translation=terrain_center,
                        orientation=sims4.math.Quaternion.IDENTITY()),
                    routing_surface=SurfaceIdentifier(
                        zone.id, 0, SurfaceType.SURFACETYPE_WORLD))
                ocean.location = location

            from objects.system import create_object
            _ocean_object = create_object(
                TerrainService.OCEAN_DEFINITION,
                post_add=move_ocean,
                loc_type=ItemLocation.FROM_OPEN_STREET)
Ejemplo n.º 2
0
 def on_finalize_load(self):
     super().on_finalize_load()
     portal_component = self.get_component(PORTAL_COMPONENT)
     if portal_component is None:
         return
     locator_manager = services.locator_manager()
     locators = locator_manager.get(
         OceanTuning.get_beach_locator_definition().id)
     initial_transforms = [locator.transform for locator in locators]
     street_instance = services.current_zone().street
     if street_instance is not None:
         for beach_data in street_instance.beaches:
             beach_forward = Vector3(beach_data.forward.x, 0,
                                     beach_data.forward.y)
             orientation = Quaternion.from_forward_vector(beach_forward)
             transform = Transform(translation=beach_data.position,
                                   orientation=orientation)
             initial_transforms.append(transform)
     if not initial_transforms:
         self._off_lot_portals_created = False
         return
     off_lot_portal_ids = []
     self._create_all_transforms_and_portals_for_initial_transforms(
         initial_transforms, store_portal_ids=off_lot_portal_ids)
     self._off_lot_portals_created = bool(off_lot_portal_ids)
     self._lot_locator_transforms = self._get_lot_locator_transforms()
     if self._lot_locator_transforms:
         self._create_all_transforms_and_portals_for_initial_transforms(
             self._lot_locator_transforms,
             lot_transforms=True,
             prior_lengths=self._lot_constraint_starts_base_lengths,
             store_portal_ids=self._lot_portals)
     if self._off_lot_portals_created or self._lot_portals:
         services.object_manager().add_portal_to_cache(self)
Ejemplo n.º 3
0
 def get_water_constraint(self, min_water_depth=None, max_water_depth=None):
     water_constraint_key = (min_water_depth, max_water_depth)
     if water_constraint_key in self._water_constraint:
         return self._water_constraint[water_constraint_key]
     if self._context.sim is not None:
         (min_water_depth, max_water_depth) = OceanTuning.make_depth_bounds_safe_for_surface_and_sim(self._routing_surface, self._context.sim, min_water_depth, max_water_depth)
     if self._target is not None:
         if self._target is not self._context.sim:
             (min_water_depth, max_water_depth) = OceanTuning.make_depth_bounds_safe_for_surface_and_sim(self._routing_surface, self._target, min_water_depth, max_water_depth)
     if self.is_for_vehicle:
         wading_interval = TunedInterval(0.1, 0.1)
         (min_water_depth, max_water_depth) = OceanTuning.make_depth_bounds_safe_for_surface(self._routing_surface, wading_interval, min_water_depth, max_water_depth)
     if min_water_depth is None and max_water_depth is None:
         constraint = ANYWHERE
     else:
         constraint = Constraint(min_water_depth=min_water_depth, max_water_depth=max_water_depth)
     self._water_constraint[water_constraint_key] = constraint
     return constraint
Ejemplo n.º 4
0
 def push_dismount_affordance(self, sim, final_location, depend_on_si=None):
     if sim.posture.is_vehicle:
         constraint = sim.posture_state.posture_constraint
     else:
         constraint = self._create_drive_posture_constraint(
             self.drive_affordance.provided_posture_type)
     radius = max(
         self.owner.routing_component.object_radius *
         self.object_radius_dismount_multiplier, self.ideal_route_radius)
     circle_constraint = None
     wading_interval = TunedInterval(0.1, 0.1)
     (min_water_depth,
      max_water_depth) = OceanTuning.make_depth_bounds_safe_for_surface(
          sim.routing_surface, wading_interval)
     if not (min_water_depth is None and max_water_depth is None):
         water_constraint = Constraint(min_water_depth=min_water_depth,
                                       max_water_depth=max_water_depth)
         if water_constraint.is_location_water_depth_valid(final_location):
             constraint = constraint.intersect(water_constraint)
         else:
             large_radius = max(self.minimum_route_distance, radius)
             circle_constraint = Circle(
                 final_location.transform.translation,
                 large_radius,
                 sim.routing_surface,
                 ideal_radius=self.ideal_route_radius,
                 los_reference_point=DEFAULT)
             water_constraint = water_constraint.intersect(
                 circle_constraint)
             if water_constraint.is_any_geometry_water_depth_valid():
                 constraint = constraint.intersect(water_constraint)
             else:
                 constraint = constraint.intersect(circle_constraint)
                 circle_constraint = None
     if circle_constraint is None:
         circle_constraint = Circle(final_location.transform.translation,
                                    radius,
                                    sim.routing_surface,
                                    ideal_radius=self.ideal_route_radius,
                                    los_reference_point=DEFAULT)
         constraint = constraint.intersect(circle_constraint)
     proxy_obj = services.terrain_service.TerrainService.create_surface_proxy_from_location(
         final_location)
     constraint = constraint.intersect(circle_constraint)
     return self._push_affordance(
         sim,
         interactions.utils.satisfy_constraint_interaction.
         SatisfyConstraintSuperInteraction,
         proxy_obj,
         depend_on_si=depend_on_si,
         constraint_to_satisfy=constraint,
         name_override='DismountVehicle')
Ejemplo n.º 5
0
 def check_for_wading(self, sim, *_, **__):
     routing_component = sim.routing_component
     if not routing_component.last_route_has_wading_nodes and not routing_component.wading_buff_handle:
         return
     wading_interval = OceanTuning.get_actor_wading_interval(sim)
     if wading_interval is None:
         return
     water_height = get_water_depth_at_location(sim.location)
     if water_height in wading_interval:
         if routing_component.wading_buff_handle is None:
             routing_component.wading_buff_handle = sim.add_buff(
                 self.wading_walkstyle_buff)
     elif routing_component.wading_buff_handle is not None:
         sim.remove_buff(routing_component.wading_buff_handle)
         routing_component.wading_buff_handle = None
    def get_wading_size(sim_info: SimInfo) -> Tuple[int, int]:
        """get_wading_size(sim_info)

        Retrieve the size of a Sim if they were to wade in a pool of water.

        :param sim_info: An instance of a Sim.
        :type sim_info: SimInfo
        :return: A tuple indicating the x and y wading size of a Sim from their origin point.
        :rtype: Tuple[int, int]
        """
        # noinspection PyBroadException
        try:
            from world.ocean_tuning import OceanTuning
        except:
            return 0, 0
        sim = CommonSimUtils.get_sim_instance(sim_info)
        if sim is None:
            return 0, 0
        wading_interval = OceanTuning.get_actor_wading_interval(sim)
        if wading_interval is None:
            return 0, 0
        return wading_interval.lower_bound, wading_interval.upper_bound
Ejemplo n.º 7
0
 def __call__(self, subjects, targets):
     subject = next(iter(subjects), None)
     if subject is None:
         return TestResult(False, 'WadingTest: Subject is None')
     target = next(iter(targets), None)
     if target is None:
         return TestResult(False, 'WadingTest: Target is None.')
     if target.is_sim:
         target = target.get_sim_instance(
             allow_hidden_flags=ALL_HIDDEN_REASONS)
         if target is None:
             return TestResult(False,
                               'WadingTest: Target Sim is not instanced.')
     if target.location is None or target.location.routing_surface is None:
         water_height = WadingIntervalTest.WATER_DEPTH_ON_LAND
     else:
         target_location = target.location.transform.translation
         water_height = get_water_depth(target_location[0],
                                        target_location[2],
                                        target.location.level)
     wading_interval = OceanTuning.get_actor_wading_interval(subject)
     return self.test.evaluate(subject, water_height, wading_interval,
                               self.negate, self.tooltip)
Ejemplo n.º 8
0
 def find_good_location_for_slave(self, master_location):
     restrictions = []
     fgl_kwargs = {}
     fgl_flags = 0
     fgl_tuning = self.fgl_on_routes
     slave_position = master_location.transform.transform_point(
         self._offset)
     orientation = master_location.transform.orientation
     routing_surface = master_location.routing_surface
     if routing_surface is None:
         master_parent = master_location.parent
         if master_parent:
             routing_surface = master_parent.routing_surface
     if self.slave.is_sim or isinstance(self.slave, StubActor):
         (min_water_depth, max_water_depth
          ) = OceanTuning.make_depth_bounds_safe_for_surface_and_sim(
              routing_surface, self.slave)
     else:
         min_water_depth = None
         max_water_depth = None
     (min_water_depth, max_water_depth
      ) = OceanTuning.make_depth_bounds_safe_for_surface_and_sim(
          routing_surface,
          self.master,
          min_water_depth=min_water_depth,
          max_water_depth=max_water_depth)
     fgl_kwargs.update({
         'min_water_depth': min_water_depth,
         'max_water_depth': max_water_depth
     })
     if fgl_tuning.height_tolerance is not None:
         fgl_kwargs['height_tolerance'] = fgl_tuning.height_tolerance
     if fgl_tuning.slave_should_face_master:
         restrictions.append(
             RelativeFacingRange(master_location.transform.translation, 0))
         fgl_kwargs.update({
             'raytest_radius':
             self.RAYTRACE_RADIUS,
             'raytest_start_offset':
             self.RAYTRACE_HEIGHT,
             'raytest_end_offset':
             self.RAYTRACE_HEIGHT,
             'ignored_object_ids': {self.master.id, self.slave.id},
             'raytest_start_point_override':
             master_location.transform.translation
         })
         fgl_flags = FGLSearchFlag.SHOULD_RAYTEST
         orientation_offset = sims4.math.angle_to_yaw_quaternion(
             sims4.math.vector3_angle(
                 sims4.math.vector_normalize(self._offset)))
         orientation = Quaternion.concatenate(orientation,
                                              orientation_offset)
     starting_location = placement.create_starting_location(
         position=slave_position,
         orientation=orientation,
         routing_surface=routing_surface)
     if self.slave.is_sim:
         fgl_flags |= FGLSearchFlagsDefaultForSim
         fgl_context = placement.create_fgl_context_for_sim(
             starting_location,
             self.slave,
             search_flags=fgl_flags,
             restrictions=restrictions,
             **fgl_kwargs)
     else:
         fgl_flags |= FGLSearchFlagsDefault
         footprint = self.slave.get_footprint()
         master_position = master_location.position if hasattr(
             master_location,
             'position') else master_location.transform.translation
         fgl_context = FindGoodLocationContext(
             starting_location,
             object_id=self.slave.id,
             object_footprints=(footprint, )
             if footprint is not None else None,
             search_flags=fgl_flags,
             restrictions=restrictions,
             connectivity_group_override_point=master_position,
             **fgl_kwargs)
     (new_position,
      new_orientation) = placement.find_good_location(fgl_context)
     if new_position is None or new_orientation is None:
         logger.warn(
             'No good location found for {} after slaved in a routing formation headed to {}.',
             self.slave,
             starting_location,
             owner='rmccord')
         return sims4.math.Transform(
             Vector3(*starting_location.position),
             Quaternion(*starting_location.orientation))
     new_position.y = services.terrain_service.terrain_object(
     ).get_routing_surface_height_at(new_position.x, new_position.z,
                                     master_location.routing_surface)
     final_transform = sims4.math.Transform(new_position, new_orientation)
     return final_transform
Ejemplo n.º 9
0
 def supports_wading_walkstyle_buff(self, actor):
     return self.wading_walkstyle_buff is not None and OceanTuning.get_actor_wading_interval(
         actor)
Ejemplo n.º 10
0
    def _apply_wading_walkstyle_to_path(self,
                                        actor,
                                        path,
                                        default_walkstyle,
                                        time_offset=None):
        if actor.is_sim and actor.sim_info.is_ghost:
            return False
        wading_interval = OceanTuning.get_actor_wading_interval(actor)
        if wading_interval is None:
            return False
        wading_walkstyle = self.get_wading_walkstyle(actor)
        if wading_walkstyle is None:
            return False

        def get_node_water_height(path_node):
            return get_water_depth(path_node.position[0],
                                   path_node.position[2],
                                   path_node.routing_surface_id.secondary_id)

        path_nodes = list(path.nodes)
        start_wading = get_node_water_height(path_nodes[0]) in wading_interval
        end_wading = get_node_water_height(path_nodes[-1]) in wading_interval
        if not start_wading and not end_wading:
            return False
        path_contains_wading = False
        for (start_node, end_node) in zip(path_nodes, path_nodes[1:]):
            if time_offset is not None and end_node.time < time_offset:
                continue
            if start_node.routing_surface_id.type == SurfaceType.SURFACETYPE_POOL:
                continue
            if start_node.portal_object_id != 0:
                continue
            start_wading = get_node_water_height(start_node) in wading_interval
            end_wading = get_node_water_height(end_node) in wading_interval
            if not start_wading and not end_wading:
                continue
            is_wading = start_wading
            if is_wading:
                start_node.walkstyle = wading_walkstyle
                path_contains_wading = True
            nodes_to_add = []
            for (transform, routing_surface,
                 time) in path.get_location_data_along_segment_gen(
                     start_node.index, end_node.index, time_step=0.3):
                should_wade = get_water_depth(
                    transform.translation[0],
                    transform.translation[2]) in wading_interval
                if is_wading and not should_wade:
                    is_wading = False
                    nodes_to_add.append(
                        (Location(transform.translation, transform.orientation,
                                  routing_surface), time, 0, default_walkstyle,
                         0, 0, end_node.index))
                elif not is_wading:
                    if should_wade:
                        is_wading = True
                        nodes_to_add.append(
                            (Location(transform.translation,
                                      transform.orientation, routing_surface),
                             time, 0, wading_walkstyle, 0, 0, end_node.index))
                        path_contains_wading = True
            running_index_offset = 0
            for (loc, time, node_type, walkstyle, portal_obj_id, portal_id,
                 index) in nodes_to_add:
                node_index = index + running_index_offset
                path.nodes.add_node(loc, time, node_type, walkstyle,
                                    portal_obj_id, portal_id, node_index)
                node = path.nodes[node_index]
                node.is_procedural = False
                running_index_offset += 1
        return path_contains_wading
Ejemplo n.º 11
0
 def _get_jig_transforms_gen(cls,
                             initiating_sim,
                             target_sim,
                             picked_object=None,
                             participant_slot_overrides=None):
     slot_map = cls.participant_slot_map if participant_slot_overrides is None else participant_slot_overrides
     actor_slot_index = slot_map.get(ParticipantType.Actor,
                                     cls.DEFAULT_SLOT_INDEX_ACTOR)
     target_slot_index = slot_map.get(ParticipantType.TargetSim,
                                      cls.DEFAULT_SLOT_INDEX_TARGET)
     if cls._can_picked_object_be_jig(picked_object):
         try:
             (actor_transform, target_transform,
              routing_surface) = get_two_person_transforms_for_jig(
                  picked_object.definition, picked_object.transform,
                  picked_object.routing_surface, actor_slot_index,
                  target_slot_index)
             yield (actor_transform, target_transform, routing_surface, ())
             return
         except RuntimeError:
             pass
     fallback_routing_surface = None
     if initiating_sim.routing_surface != target_sim.routing_surface:
         if initiating_sim.routing_surface.type == routing.SurfaceType.SURFACETYPE_WORLD:
             fallback_routing_surface = initiating_sim.routing_surface
         else:
             fallback_routing_surface = target_sim.routing_surface
     fallback_starting_position = None
     stay_in_connectivity_group = True
     ignore_restrictions = False
     if target_sim is not None:
         if target_sim.routing_surface.type == SurfaceType.SURFACETYPE_POOL:
             fallback_routing_surface = SurfaceIdentifier(
                 target_sim.routing_surface.primary_id,
                 target_sim.routing_surface.secondary_id,
                 SurfaceType.SURFACETYPE_WORLD)
             ocean = services.terrain_service.ocean_object()
             if not ocean is None:
                 if not target_sim.in_pool:
                     if not services.active_lot().is_position_on_lot(
                             target_sim.position):
                         extended_species = target_sim.extended_species
                         age = target_sim.age
                         start_location = ocean.get_nearest_constraint_start_location(
                             extended_species, age, target_sim.position,
                             WaterDepthIntervals.WET)
                         if start_location is not None:
                             fallback_starting_position = start_location.transform.translation
             stay_in_connectivity_group = False
             ignore_restrictions = True
     reference_routing_surface = initiating_sim.routing_surface if target_sim is None else target_sim.routing_surface
     (min_water_depth, max_water_depth
      ) = OceanTuning.make_depth_bounds_safe_for_surface_and_sim(
          reference_routing_surface, initiating_sim)
     if target_sim is not None:
         (min_water_depth, max_water_depth
          ) = OceanTuning.make_depth_bounds_safe_for_surface_and_sim(
              reference_routing_surface, target_sim, min_water_depth,
              max_water_depth)
     if fallback_routing_surface is not None:
         (fallback_min_water_depth, fallback_max_water_depth
          ) = OceanTuning.make_depth_bounds_safe_for_surface_and_sim(
              fallback_routing_surface, initiating_sim)
         if target_sim is not None:
             (fallback_min_water_depth, fallback_max_water_depth
              ) = OceanTuning.make_depth_bounds_safe_for_surface_and_sim(
                  fallback_routing_surface, target_sim,
                  fallback_min_water_depth, fallback_max_water_depth)
     else:
         fallback_min_water_depth = None
         fallback_max_water_depth = None
     yield from cls.jig.get_transforms_gen(
         initiating_sim,
         target_sim,
         actor_slot_index=actor_slot_index,
         target_slot_index=target_slot_index,
         stay_outside=cls.stay_outside,
         fallback_routing_surface=fallback_routing_surface,
         fallback_min_water_depth=fallback_min_water_depth,
         fallback_max_water_depth=fallback_max_water_depth,
         fallback_starting_position=fallback_starting_position,
         stay_in_connectivity_group=stay_in_connectivity_group,
         ignore_restrictions=ignore_restrictions,
         min_water_depth=min_water_depth,
         max_water_depth=max_water_depth)