Пример #1
0
 def _get_duration_for_cycle(self, clip, walkstyle_info_dict):
     builder_name = hash_util.hash32(clip)
     if builder_name not in walkstyle_info_dict:
         logger.error(
             "Can't find the ladder clip {} in the  walkstyle info.", clip)
         return 0
     return walkstyle_info_dict[builder_name][self.walkstyle_duration]
Пример #2
0
 def to_slot_hash(slot_name_or_hash):
     if slot_name_or_hash is None:
         return 0
     if isinstance(slot_name_or_hash, int):
         return slot_name_or_hash
     else:
         return hash_util.hash32(slot_name_or_hash)
Пример #3
0
 def _add_fish_effect(self, fish):
     if None in self._fish_vfx_handles:
         index = self._fish_vfx_handles.index(None)
     else:
         index = len(self._fish_vfx_handles)
         self._fish_vfx_handles.append(None)
     vfx_data = fish.inventory_to_fish_vfx.get(
         self.inventory_component.inventory_type, None)
     if vfx_data is not None:
         vfx_index = index + 1
         if self.fish_vfx_prefix is not None:
             vfx_name = '{}_{}_{}'.format(self.fish_vfx_prefix,
                                          vfx_data.vfx_name, vfx_index)
         else:
             vfx_name = '{}_{}'.format(vfx_data.vfx_name, vfx_index)
         vfx_slot_name = '{}{}'.format(vfx_data.vfx_base_bone_name,
                                       vfx_index)
     else:
         vfx_name = fish.fishbowl_vfx
         vfx_slot_name = self.VFX_SLOT_NAME
     vfx_slot = hash_util.hash32(vfx_slot_name)
     play_effect_handle = vfx.PlayEffect(self,
                                         vfx_name,
                                         joint_name=vfx_slot)
     play_effect_handle.start()
     self._fish_vfx_handles[index] = (fish.id, play_effect_handle)
Пример #4
0
 def _find_slot_name(self, slot_type, check_occupied=False):
     slot_name = slot_type._bone_name + self.part_suffix
     if check_occupied:
         slot_hash = hash32(slot_name)
         for child in self.children:
             while child.location.joint_name_hash == slot_hash:
                 return
     return slot_name
Пример #5
0
 def _find_slot_name(self, slot_type, check_occupied=False):
     slot_name = slot_type._bone_name + self.part_suffix
     if check_occupied:
         slot_hash = hash32(slot_name)
         for child in self.children:
             while child.location.joint_name_hash == slot_hash:
                 return
     return slot_name
Пример #6
0
 def get_joint_transform_for_joint(self, joint_name):
     if isinstance(joint_name, str):
         joint_name = joint_name + str(self.subroot_index)
     else:
         joint_name = hash32(str(self.subroot_index),
                             initial_hash=joint_name)
     transform = get_joint_transform_from_rig(self.rig, joint_name)
     transform = Transform.concatenate(transform, self.part_owner.transform)
     return transform
Пример #7
0
 def get_bone_name_hashes_for_part_suffix(cls, part_suffix):
     if cls._bone_name_hashes_for_part_suffices is None:
         cls._bone_name_hashes_for_part_suffices = {}
     if part_suffix in cls._bone_name_hashes_for_part_suffices:
         return cls._bone_name_hashes_for_part_suffices[part_suffix]
     bone_names = cls.get_bone_names_for_part_suffix(part_suffix)
     bone_name_hashes = frozenset(hash32(bone_name) for bone_name in bone_names)
     cls._bone_name_hashes_for_part_suffices[part_suffix] = bone_name_hashes
     return bone_name_hashes
Пример #8
0
 def get_bone_name_hashes_for_part_suffix(cls, part_suffix):
     if cls._bone_name_hashes_for_part_suffices is None:
         cls._bone_name_hashes_for_part_suffices = {}
     if part_suffix in cls._bone_name_hashes_for_part_suffices:
         return cls._bone_name_hashes_for_part_suffices[part_suffix]
     bone_names = cls.get_bone_names_for_part_suffix(part_suffix)
     bone_name_hashes = frozenset(
         hash32(bone_name) for bone_name in bone_names)
     cls._bone_name_hashes_for_part_suffices[part_suffix] = bone_name_hashes
     return bone_name_hashes
Пример #9
0
    def spawn_objects(self, position):
        root = sims4.math.Vector3(float(position.x), 0, float(position.z))
        zone = services.current_zone()
        lot = zone.lot
        if not self.contained_in_lot(lot, root):
            closest_point = self.find_nearest_point_on_lot(lot, root)
            if closest_point is None:
                return False
            radius = (self.top_right_pos - self.bottom_left_pos).magnitude_2d()/2
            root = closest_point + sims4.math.vector_normalize(sims4.math.vector_flatten(lot.center) - closest_point)*(radius + 1)
            if not self.contained_in_lot(lot, root):
                sims4.log.warn('Placement', "Placed the lot objects but the entire bounding box isn't inside the lot. This is ok. If you need them to be inside the lot run the interaction again at a diffrent location.")

        def _generate_vector(offset_x, offset_z):
            ground_obj = services.terrain_service.terrain_object()
            ret_vector = sims4.math.Vector3(root.x + offset_x, 0, root.z + offset_z)
            ret_vector.y = ground_obj.get_height_at(ret_vector.x, ret_vector.z)
            return ret_vector

        def _generate_quat(rot):
            return sims4.math.Quaternion.from_axis_angle(rot, sims4.math.Vector3(0, 1, 0))

        for info in self.setup_lot_objects:
            new_pos = _generate_vector(info.position.x, info.position.y)
            new_rot = _generate_quat(sims4.math.PI/180*info.angle)
            new_obj = self._create_object(info.definition, new_pos, new_rot)
            if new_obj is None:
                sims4.log.error('SetupLot', 'Unable to create object: {}', info)
            for state_value in info.init_state_values:
                new_obj.set_state(state_value.state, state_value)
            for child_info in info.children:
                slot_owner = new_obj
                if child_info.part_index is not None:
                    for obj_part in new_obj.parts:
                        while obj_part.subroot_index == child_info.part_index:
                            slot_owner = obj_part
                            break
                bone_name_hash = None
                if child_info.bone_name is not None:
                    bone_name_hash = hash32(child_info.bone_name)
                slot_type = None
                if child_info.slot_type is not None:
                    slot_type = child_info.slot_type
                while True:
                    for runtime_slot in slot_owner.get_runtime_slots_gen(slot_types={slot_type}, bone_name_hash=bone_name_hash):
                        while runtime_slot.is_valid_for_placement(definition=child_info.definition):
                            break
                    sims4.log.error('SetupLot', 'Unable to find slot for child object: {}', child_info)
                child = self._create_object(child_info.definition)
                if child is None:
                    sims4.log.error('SetupLot', 'Unable to create child object: {}', child_info)
                runtime_slot.add_child(child)
                for state_value in child_info.init_state_values:
                    child.set_state(state_value.state, state_value)
Пример #10
0
 def get_bone_name_hashes_for_part_suffix(cls, part_suffix):
     if cls._bone_name_hashes_for_part_suffices is None:
         cls._bone_name_hashes_for_part_suffices = {}
     if part_suffix in cls._bone_name_hashes_for_part_suffices:
         return cls._bone_name_hashes_for_part_suffices[part_suffix]
     bone_name_hashes = set()
     if cls.subroot is not None:
         for bone_name_hash in cls.subroot.bone_names:
             if part_suffix is not None:
                 bone_name_hash = hash32(str(part_suffix),
                                         initial_hash=bone_name_hash)
             bone_name_hashes.add(bone_name_hash)
     cls._bone_name_hashes_for_part_suffices[part_suffix] = frozenset(
         bone_name_hashes)
     return cls._bone_name_hashes_for_part_suffices[part_suffix]
Пример #11
0
 def to_slot_hash(slot_name_or_hash):
     if slot_name_or_hash is None:
         return 0
     if isinstance(slot_name_or_hash, int):
         return slot_name_or_hash
     return hash_util.hash32(slot_name_or_hash)
Пример #12
0
    def spawn_objects(self, position):
        root = sims4.math.Vector3(position.x, position.y, position.z)
        zone = services.current_zone()
        lot = zone.lot
        owner_id = lot.owner_household_id
        if not self.contained_in_lot(lot, root):
            closest_point = self.find_nearest_point_on_lot(lot, root)
            if closest_point is None:
                return False
            radius = (self.top_right_pos -
                      self.bottom_left_pos).magnitude_2d() / 2
            root = closest_point + sims4.math.vector_normalize(
                sims4.math.vector_flatten(lot.center) -
                closest_point) * (radius + 1)
            if not self.contained_in_lot(lot, root):
                sims4.log.warn(
                    'Placement',
                    "Placed the lot objects but the entire bounding box isn't inside the lot. This is ok. If you need them to be inside the lot run the interaction again at a diffrent location."
                )

        def _generate_vector(offset_x, offset_z):
            ground_obj = services.terrain_service.terrain_object()
            ret_vector = sims4.math.Vector3(root.x + offset_x, root.y,
                                            root.z + offset_z)
            ret_vector.y = ground_obj.get_height_at(ret_vector.x, ret_vector.z)
            return ret_vector

        def _generate_quat(rot):
            return sims4.math.Quaternion.from_axis_angle(
                rot, sims4.math.Vector3(0, 1, 0))

        for info in self.setup_lot_objects:
            new_pos = _generate_vector(info.position.x, info.position.y)
            new_rot = _generate_quat(sims4.math.PI / 180 * info.angle)
            new_obj = self._create_object(info.definition,
                                          new_pos,
                                          new_rot,
                                          owner_id=owner_id)
            if new_obj is None:
                sims4.log.error('SetupLot', 'Unable to create object: {}',
                                info)
            else:
                for state_value in info.init_state_values:
                    new_obj.set_state(state_value.state, state_value)
                for child_info in info.children:
                    slot_owner = new_obj
                    if child_info.part_index is not None:
                        for obj_part in new_obj.parts:
                            if obj_part.subroot_index == child_info.part_index:
                                slot_owner = obj_part
                                break
                    bone_name_hash = None
                    if child_info.bone_name is not None:
                        bone_name_hash = hash32(child_info.bone_name)
                    slot_type = None
                    if child_info.slot_type is not None:
                        slot_type = child_info.slot_type
                    for runtime_slot in slot_owner.get_runtime_slots_gen(
                            slot_types={slot_type},
                            bone_name_hash=bone_name_hash):
                        if runtime_slot.is_valid_for_placement(
                                definition=child_info.definition):
                            break
                    else:
                        sims4.log.error(
                            'SetupLot',
                            'Unable to find slot for child object: {}',
                            child_info)
                    child = self._create_object(child_info.definition,
                                                owner_id=owner_id)
                    if child is None:
                        sims4.log.error('SetupLot',
                                        'Unable to create child object: {}',
                                        child_info)
                    else:
                        runtime_slot.add_child(child)
                        for state_value in child_info.init_state_values:
                            child.set_state(state_value.state, state_value)
Пример #13
0
class _PortalTypeDataStairs(_PortalTypeDataBase):
    STAIR_SHOO_POLYGON_PADDING = Tunable(
        description=
        '\n        When a sim uses a stair case with a stair landing, any sims who are\n        in the way will be shooed. The polygon that determines which sims are\n        shooed is based on the portals on that landing, but can be padded using\n        this constant.\n        ',
        tunable_type=float,
        default=0.3)
    FACTORY_TUNABLES = {
        'supports_landing_shoo':
        Tunable(
            description=
            '\n            If True, sims standing on a stair landing on the object on which\n            this portal exists will be shooed from the path of the stairs if\n            another sim attempts to use the stairs. This is to avoid clipping.\n            ',
            tunable_type=bool,
            default=False)
    }
    STAIRS_DOWN_CYCLE = hash_util.hash32('stairs_down_cycle')
    STAIRS_DOWN_CYCLE_R = hash_util.hash32('stairs_down_cycle_r')
    STAIRS_UP_CYCLE = hash_util.hash32('stairs_up_cycle')
    STAIRS_UP_CYCLE_R = hash_util.hash32('stairs_up_cycle_r')
    SPEED_OVERRIDE = hash_util.hash32('speed_override')

    @property
    def portal_type(self):
        return PortalType.PortalType_Animate

    def get_stair_count(self, obj):
        return build_buy.get_stair_count(obj.id)

    def get_additional_required_portal_flags(self, entry_location,
                                             exit_location):
        if entry_location.routing_surface == exit_location.routing_surface:
            return PortalFlags.STAIRS_PORTAL_SHORT
        else:
            return PortalFlags.STAIRS_PORTAL_LONG
        return 0

    def notify_in_use(self, user, portal_instance, portal_object):
        if self.supports_landing_shoo:
            routing_surface = None
            exit_location = portal_instance.there_exit
            if exit_location.routing_surface.type == SurfaceType.SURFACETYPE_OBJECT:
                exit_height = terrain.get_terrain_height(
                    exit_location.position.x,
                    exit_location.position.z,
                    routing_surface=exit_location.routing_surface)
                routing_surface = exit_location.routing_surface
                landing_points = []
                for (there_start, there_end, back_start, back_end,
                     _) in self.get_portal_locations(portal_object):
                    for portal_location in (there_start, there_end, back_start,
                                            back_end):
                        if portal_location.routing_surface.type == SurfaceType.SURFACETYPE_OBJECT:
                            portal_height = terrain.get_terrain_height(
                                portal_location.position.x,
                                portal_location.position.z,
                                routing_surface=portal_location.routing_surface
                            )
                            if math.isclose(portal_height, exit_height):
                                landing_points.append(portal_location.position)
                polygon = Polygon(landing_points)
                polygon = polygon.get_convex_hull()
                polygon = inflate_polygon(
                    polygon, _PortalTypeDataStairs.STAIR_SHOO_POLYGON_PADDING)
                UserFootprintHelper.force_move_sims_in_polygon(
                    polygon, routing_surface, exclude=(user, ))

    def add_portal_data(self, actor, portal_instance, is_mirrored, walkstyle):
        node_data = routing_protocols.RouteNodeData()
        obj = portal_instance.obj
        stair_count = self.get_stair_count(obj)
        node_data.type = routing_protocols.RouteNodeData.DATA_STAIRS
        op = routing_protocols.RouteStairsData()
        op.traversing_up = not is_mirrored
        op.stair_count = stair_count
        op.walkstyle = walkstyle
        op.stairs_per_cycle = 1
        node_data.data = op.SerializeToString()
        node_data.do_stop_transition = True
        node_data.do_start_transition = True
        return node_data

    def get_portal_duration(self, portal_instance, is_mirrored, walkstyle, age,
                            gender, species):
        walkstyle_info_dict = routing.get_walkstyle_info_full(
            walkstyle, age, gender, species)
        obj = portal_instance.obj
        stair_count = self.get_stair_count(obj)
        builder_name = self.STAIRS_DOWN_CYCLE if is_mirrored else self.STAIRS_UP_CYCLE
        if builder_name not in walkstyle_info_dict:
            builder_name = self.STAIRS_DOWN_CYCLE_R if is_mirrored else self.STAIRS_UP_CYCLE_R
            if builder_name not in walkstyle_info_dict:
                speed_override = routing.get_walkstyle_property(
                    walkstyle, age, gender, species, self.SPEED_OVERRIDE)
                if speed_override is None:
                    logger.error(
                        'Failed to find stair builder or speed_override for walkstyle {}.',
                        walkstyle)
                    return 0
                return speed_override * stair_count
        info = walkstyle_info_dict[builder_name]
        duration = info['duration'] * stair_count
        return duration

    def get_portal_locations(self, obj):
        stair_lanes = routing.get_stair_portals(obj.id, obj.zone_id)
        if not stair_lanes:
            return ()
        locations = []
        for lane in stair_lanes:
            ((there_start, there_end), (back_start, back_end)) = lane
            (there_start_position, there_start_routing_surface) = there_start
            (there_end_position, there_end_routing_surface) = there_end
            (back_start_position, back_start_routing_surface) = back_start
            (back_end_position, back_end_routing_surface) = back_end
            if there_start_routing_surface == there_end_routing_surface:
                required_flags = PortalFlags.STAIRS_PORTAL_SHORT
            else:
                required_flags = PortalFlags.STAIRS_PORTAL_LONG
            locations.append(
                (Location(there_start_position,
                          routing_surface=there_start_routing_surface),
                 Location(there_end_position,
                          routing_surface=there_end_routing_surface),
                 Location(back_start_position,
                          routing_surface=back_start_routing_surface),
                 Location(back_end_position,
                          routing_surface=back_end_routing_surface),
                 required_flags))
        return locations
Пример #14
0
class TerrainTag(enum.Int):
    INVALID = 0
    BRICK = hash_util.hash32('brick')
    CARPET = hash_util.hash32('carpet')
    CEMENT = hash_util.hash32('cement')
    DIRT = hash_util.hash32('dirt')
    GRASS = hash_util.hash32('grass')
    GRAVEL = hash_util.hash32('gravel')
    HARDWOOD = hash_util.hash32('hardwood')
    LEAVES = hash_util.hash32('leaves')
    LINOLEUM = hash_util.hash32('linoleum')
    MARBLE = hash_util.hash32('marble')
    METAL = hash_util.hash32('metal')
    PUDDLE = hash_util.hash32('puddle')
    SAND = hash_util.hash32('sand')
    SNOW = hash_util.hash32('snow')
    STONE = hash_util.hash32('stone')
    WOOD_DECK = hash_util.hash32('wood deck')
Пример #15
0
 def _tuning_loaded_callback(cls):
     cls.slot_type = cls
     if cls._bone_name:
         cls.bone_name_hash = hash32(cls._bone_name)