def constraint_gen(cls, inst, sim, target, participant_type, *args, **kwargs): if inst is not None and inst._edge_constraint is not None: yield inst._edge_constraint return inst_or_cls = cls if inst is None else inst pick_position = inst_or_cls.context.pick if pick_position is None: pick_position = target.position else: pick_position = pick_position.location pool_block_id = build_buy.get_block_id(sim.zone_id, pick_position, inst_or_cls.context.pick.level - 1) if pool_block_id == 0: if inst_or_cls.context.pick.routing_surface.type == SurfaceType.SURFACETYPE_POOL: if get_water_depth(sim.position.x, sim.position.z, sim.level) > 0: pool_edge_constraints = ANYWHERE else: pool_edge_constraints = OceanStartLocationConstraint.create_simple_constraint(WaterDepthIntervals.WET, 1, sim, target) return else: return else: pool = pool_utils.get_pool_by_block_id(pool_block_id) if pool is None: return pool_edge_constraints = pool.get_edge_constraint(constraint_width=inst_or_cls.edge_constraint_width, inward_dir=False, return_constraint_list=True, los_reference_point=pick_position) constraint_set = create_constraint_set(pool_edge_constraints) inst._edge_constraint = constraint_set yield constraint_set
def get_water_depth_at(x: float, z: float, surface_level: int=0) -> float: """get_water_depth_at(x, z, surface_level=0) Determine the water depth at the specified coordinates. :param x: The X coordinate. :type x: float :param z: The Z coordinate. :type z: float :param surface_level: The surface level. Default is 0. :type surface_level: int, optional :return: The depth of the water at the specified coordinates. :rtype: float """ return terrain.get_water_depth(x, z, level=surface_level)
def get_default_position(self, position=None): front_door = services.get_door_service().get_front_door() if front_door is not None: default_position = front_door.position elif position is not None: default_position = min(self.corners, key=lambda p: (p - position).magnitude_squared()) else: plex_service = services.get_plex_service() if plex_service.get_plex_building_type( services.current_zone_id()) == PlexBuildingType.COASTAL: for corner_position in self.corners: if get_water_depth(corner_position.x, corner_position.z) <= 0: default_position = corner_position break else: logger.error( "Couldn't find a corner that was not below water on the current lot. This is probably an error case. We need a place to put down things like the mailbox, etc." ) default_position = self.corners[0] else: default_position = self.corners[0] delta = self.position - default_position if not sims4.math.vector3_almost_equal(delta, sims4.math.Vector3.ZERO()): default_position += vector_normalize(delta) if front_door is not None: plex_service = services.get_plex_service() if plex_service.is_active_zone_a_plex(): (front_position, back_position) = front_door.get_door_positions() if front_position is not None: front_zone_id = plex_service.get_plex_zone_at_position( front_position, front_door.level) else: front_zone_id = None if front_zone_id is not None: default_position = front_position elif back_position is not None: back_zone_id = plex_service.get_plex_zone_at_position( back_position, front_door.level) if back_zone_id is not None: default_position = back_position return default_position
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)
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)
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
def _get_water_depth_at_edge(i): transform = edge_transforms[i] translation = transform.translation + transform.orientation.transform_vector( Ocean.EDGE_TEST_POINT_OFFSET) return get_water_depth(translation.x, translation.z)