当前位置: 首页>>代码示例>>Python>>正文


Python Vec.as_tuple方法代码示例

本文整理汇总了Python中srctools.Vec.as_tuple方法的典型用法代码示例。如果您正苦于以下问题:Python Vec.as_tuple方法的具体用法?Python Vec.as_tuple怎么用?Python Vec.as_tuple使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在srctools.Vec的用法示例。


在下文中一共展示了Vec.as_tuple方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。

示例1: join_markers

# 需要导入模块: from srctools import Vec [as 别名]
# 或者: from srctools.Vec import as_tuple [as 别名]
def join_markers(inst_a, inst_b, is_start=False):
    """Join two marker ents together with corners.

    This returns a list of solids used for the vphysics_motion trigger.
    """
    origin_a = Vec.from_str(inst_a['ent']['origin'])
    origin_b = Vec.from_str(inst_b['ent']['origin'])

    norm_a = Vec(-1, 0, 0).rotate_by_str(inst_a['ent']['angles'])
    norm_b = Vec(-1, 0, 0).rotate_by_str(inst_b['ent']['angles'])

    config = inst_a['conf']

    if norm_a == norm_b:
        # Either straight-line, or s-bend.
        dist = (origin_a - origin_b).mag()

        if origin_a + (norm_a * dist) == origin_b:
            make_straight(
                origin_a,
                norm_a,
                dist,
                config,
                is_start,
            )
        # else: S-bend, we don't do the geometry for this..
        return

    if norm_a == -norm_b:
        # U-shape bend..
        make_ubend(
            origin_a,
            origin_b,
            norm_a,
            config,
            max_size=inst_a['size'],
        )
        return

    try:
        corner_ang, flat_angle = CORNER_ANG[norm_a.as_tuple(), norm_b.as_tuple()]

        if origin_a[flat_angle] != origin_b[flat_angle]:
            # It needs to be flat in this angle!
            raise ValueError
    except ValueError:
        # The tubes need two corners to join together - abort for that.
        return
    else:
        make_bend(
            origin_a,
            origin_b,
            norm_a,
            norm_b,
            corner_ang,
            config,
            max_size=inst_a['size'],
        )
开发者ID:BenVlodgi,项目名称:BEE2.4,代码行数:60,代码来源:vactubes.py

示例2: res_glass_hole

# 需要导入模块: from srctools import Vec [as 别名]
# 或者: from srctools.Vec import as_tuple [as 别名]
def res_glass_hole(inst: Entity, res: Property):
    """Add Glass/grating holes. The value should be 'large' or 'small'."""
    hole_type = HoleType(res.value)

    normal = Vec(z=-1).rotate_by_str(inst['angles'])
    origin = Vec.from_str(inst['origin']) // 128 * 128 + 64

    if test_hole_spot(origin, normal, hole_type):
        HOLES[origin.as_tuple(), normal.as_tuple()] = hole_type
        inst['origin'] = origin
        inst['angles'] = normal.to_angle()
        return

    # Test the opposite side of the glass too.

    inv_origin = origin + 128 * normal
    inv_normal = -normal

    if test_hole_spot(inv_origin, inv_normal, hole_type):
        HOLES[inv_origin.as_tuple(), inv_normal.as_tuple()] = hole_type
        inst['origin'] = inv_origin
        inst['angles'] = inv_normal.to_angle()
    else:
        # Remove the instance, so this does nothing.
        inst.remove()
开发者ID:BenVlodgi,项目名称:BEE2.4,代码行数:27,代码来源:barriers.py

示例3: make_straight

# 需要导入模块: from srctools import Vec [as 别名]
# 或者: from srctools.Vec import as_tuple [as 别名]
def make_straight(
        origin: Vec,
        normal: Vec,
        dist: int,
        config: dict,
        is_start=False,
    ):
    """Make a straight line of instances from one point to another."""

    # 32 added to the other directions, plus extended dist in the direction
    # of the normal - 1
    p1 = origin + (normal * ((dist // 128 * 128) - 96))
    # The starting brush needs to
    # stick out a bit further, to cover the
    # point_push entity.
    p2 = origin - (normal * (96 if is_start else 32))

    # bbox before +- 32 to ensure the above doesn't wipe it out
    p1, p2 = Vec.bbox(p1, p2)

    solid = vbsp.VMF.make_prism(
        # Expand to 64x64 in the other two directions
        p1 - 32, p2 + 32,
        mat='tools/toolstrigger',
    ).solid

    motion_trigger(solid.copy())

    push_trigger(origin, normal, [solid])

    angles = normal.to_angle()

    support_file = config['support']
    straight_file = config['straight']
    support_positions = (
        SUPPORT_POS[normal.as_tuple()]
        if support_file else
        []
    )

    for off in range(0, int(dist), 128):
        position = origin + off * normal
        vbsp.VMF.create_ent(
            classname='func_instance',
            origin=position,
            angles=angles,
            file=straight_file,
        )

        for supp_ang, supp_off in support_positions:
            if (position + supp_off).as_tuple() in SOLIDS:
                vbsp.VMF.create_ent(
                    classname='func_instance',
                    origin=position,
                    angles=supp_ang,
                    file=support_file,
                )
开发者ID:BenVlodgi,项目名称:BEE2.4,代码行数:59,代码来源:vactubes.py

示例4: test_hole_spot

# 需要导入模块: from srctools import Vec [as 别名]
# 或者: from srctools.Vec import as_tuple [as 别名]
def test_hole_spot(origin: Vec, normal: Vec, hole_type: HoleType):
    """Check if the given position is valid for holes.

    We need to check that it's actually placed on glass/grating, and that
    all the parts are the same. Otherwise it'd collide with the borders.
    """

    try:
        center_type = BARRIERS[origin.as_tuple(), normal.as_tuple()]
    except KeyError:
        LOGGER.warning('No center barrier at {}, {}', origin, normal)
        return False

    if hole_type is HoleType.SMALL:
        return True

    u, v = Vec.INV_AXIS[normal.axis()]
    # The corners don't matter, but all 4 neighbours must be there.
    for u_off, v_off in [
        (-128, 0),
        (0, -128),
        (128, 0),
        (0, 128),
    ]:
        pos = origin + Vec.with_axes(u, u_off, v, v_off)
        try:
            off_type = BARRIERS[pos.as_tuple(), normal.as_tuple()]
        except KeyError:
            # No side
            LOGGER.warning('No offset barrier at {}, {}', pos, normal)
            return False
        if off_type is not center_type:
            # Different type.
            LOGGER.warning('Wrong barrier type at {}, {}', pos, normal)
            return False
    return True
开发者ID:BenVlodgi,项目名称:BEE2.4,代码行数:38,代码来源:barriers.py

示例5: mon_remove_bullseyes

# 需要导入模块: from srctools import Vec [as 别名]
# 或者: from srctools.Vec import as_tuple [as 别名]
def mon_remove_bullseyes(inst: Entity) -> Optional[object]:
    """Remove bullsyes used for cameras."""
    if not BULLSYE_LOCS:
        return RES_EXHAUSTED

    if inst['file'].casefold() not in instanceLocs.resolve('<ITEM_CATAPULT_TARGET>'):
        return

    origin = Vec(0, 0, -64)
    origin.localise(Vec.from_str(inst['origin']), Vec.from_str(inst['angles']))
    origin = origin.as_tuple()

    LOGGER.info('Pos: {} -> ', origin, BULLSYE_LOCS[origin])

    if BULLSYE_LOCS[origin]:
        BULLSYE_LOCS[origin] -= 1
        inst.remove()
开发者ID:BenVlodgi,项目名称:BEE2.4,代码行数:19,代码来源:monitor.py

示例6: res_hollow_brush

# 需要导入模块: from srctools import Vec [as 别名]
# 或者: from srctools.Vec import as_tuple [as 别名]
def res_hollow_brush(inst: Entity, res: Property):
    """Hollow out the attached brush, as if EmbeddedVoxel was set.

    This just removes the surface if it's already an embeddedVoxel. This allows
    multiple items to embed thinly in the same block without affecting each
    other.
    """
    loc = Vec(0, 0, -64).rotate_by_str(inst['angles'])
    loc += Vec.from_str(inst['origin'])

    try:
        group = SOLIDS[loc.as_tuple()]
    except KeyError:
        LOGGER.warning('No brush for hollowing at ({})', loc)
        return  # No brush here?

    conditions.hollow_block(
        group,
        remove_orig_face=srctools.conv_bool(res['RemoveFace', False])
    )
开发者ID:BenVlodgi,项目名称:BEE2.4,代码行数:22,代码来源:brushes.py

示例7: make_barriers

# 需要导入模块: from srctools import Vec [as 别名]
# 或者: from srctools.Vec import as_tuple [as 别名]
def make_barriers(vmf: VMF, get_tex: Callable[[str], str]):
    """Make barrier entities. get_tex is vbsp.get_tex."""
    glass_temp = template_brush.get_scaling_template(
        vbsp_options.get(str, "glass_template")
    )
    grate_temp = template_brush.get_scaling_template(
        vbsp_options.get(str, "grating_template")
    )
    # Avoid error without this package.
    if HOLES:
        # Grab the template solids we need.
        hole_temp = template_brush.get_template(
            vbsp_options.get(str, 'glass_hole_temp')
        )
        hole_world, hole_detail, _ = hole_temp.visgrouped({'small'})
        hole_temp_small = hole_world + hole_detail
        hole_world, hole_detail, _ = hole_temp.visgrouped({'large'})
        hole_temp_large = hole_world + hole_detail
        hole_world, hole_detail, _ = hole_temp.visgrouped({'large_corner'})
        hole_temp_corner = hole_world + hole_detail
    else:
        hole_temp_small = hole_temp_large = hole_temp_corner = None

    floorbeam_temp = vbsp_options.get(str, 'glass_floorbeam_temp')

    if vbsp_options.get_itemconf('BEE_PELLET:PelletGrating', False):
        # Merge together these existing filters in global_pti_ents
        vmf.create_ent(
            origin=vbsp_options.get(Vec, 'global_pti_ents_loc'),
            targetname='@grating_filter',
            classname='filter_multi',
            filtertype=0,
            negated=0,
            filter01='@not_pellet',
            filter02='@not_paint_bomb',
        )
    else:
        # Just skip paint bombs.
        vmf.create_ent(
            origin=vbsp_options.get(Vec, 'global_pti_ents_loc'),
            targetname='@grating_filter',
            classname='filter_activator_class',
            negated=1,
            filterclass='prop_paint_bomb',
        )

    # Group the positions by planes in each orientation.
    # This makes them 2D grids which we can optimise.
    # (normal_dist, positive_axis, type) -> [(x, y)]
    slices = defaultdict(set)  # type: Dict[Tuple[Tuple[float, float, float], bool, BarrierType], Set[Tuple[float, float]]]
    # We have this on the 32-grid so we can cut squares for holes.

    for (origin, normal), barr_type in BARRIERS.items():
        origin = Vec(origin)
        normal = Vec(normal)
        norm_axis = normal.axis()
        u, v = origin.other_axes(norm_axis)
        norm_pos = Vec.with_axes(norm_axis, origin)
        slice_plane = slices[
            norm_pos.as_tuple(),  # distance from origin to this plane.
            normal[norm_axis] > 0,
            barr_type,
        ]
        for u_off in [-48, -16, 16, 48]:
            for v_off in [-48, -16, 16, 48]:
                slice_plane.add((
                    (u + u_off) // 32,
                    (v + v_off) // 32,
                ))

    # Remove pane sections where the holes are. We then generate those with
    # templates for slanted parts.
    for (origin, normal), hole_type in HOLES.items():
        barr_type = BARRIERS[origin, normal]

        origin = Vec(origin)
        normal = Vec(normal)
        norm_axis = normal.axis()
        u, v = origin.other_axes(norm_axis)
        norm_pos = Vec.with_axes(norm_axis, origin)
        slice_plane = slices[
            norm_pos.as_tuple(),
            normal[norm_axis] > 0,
            barr_type,
        ]
        if hole_type is HoleType.LARGE:
            offsets = (-80, -48, -16, 16, 48, 80)
            hole_temp = hole_temp_large.copy()
        else:
            offsets = (-16, 16)
            hole_temp = hole_temp_small.copy()
        for u_off in offsets:
            for v_off in offsets:
                # Skip the corners on large holes.
                # Those aren't actually used, so skip them. That way
                # we can have them diagonally or  without glass in the corner.
                if u_off in (-80, 80) and v_off in (-80, 80):
                    continue

                slice_plane.discard((
#.........这里部分代码省略.........
开发者ID:BenVlodgi,项目名称:BEE2.4,代码行数:103,代码来源:barriers.py

示例8: make_ubend

# 需要导入模块: from srctools import Vec [as 别名]
# 或者: from srctools.Vec import as_tuple [as 别名]

#.........这里部分代码省略.........
            3,
            max_size,
            side_dist // (128 * 2),
        )
        first_straight = second_straight = 0
        side_straight = side_dist - 2 * 128 * first_size
    elif out_off > 0:
        # The second tube is further away than the first - the first bend
        # should be largest.
        # We need 1 spot for the second bend.
        first_size = min(
            3,
            max_size,
            side_dist // 128 - 1,
            out_off,
        )
        second_size = min(3, side_dist // 128 - first_size, max_size)

        first_straight = (out_off + 128) - 128 * second_size
        second_straight = (first_size - second_size) * 128

        side_straight = (side_dist / 128 - first_size - second_size) * 128

    elif out_off < 0:
        # The first tube is further away than the second - the second bend
        # should be largest.
        second_size = min(
            3,
            max_size,
            side_dist // 128 - 1,
            -out_off  # -out = abs()
        )
        first_size = min(3, side_dist // 128 - second_size, max_size)

        first_straight = (second_size - first_size) * 128
        second_straight = (-out_off + 128) - 128 * second_size

        side_straight = (side_dist / 128 - first_size - second_size) * 128
    else:
        return []  # Not possible..

    # We always have a straight segment at the first marker point - move
    # everything up slightly.

    first_straight += 128

    LOGGER.info(
        'Ubend {}: {}, c={}, {}, c={}, {}',
        out_off,
        first_straight,
        first_size,
        side_straight,
        second_size,
        second_straight,
    )

    make_straight(
        origin_a,
        normal,
        first_straight,
        config,
        is_start,
    )

    first_corner_loc = origin_a + (normal * first_straight)

    make_corner(
        first_corner_loc,
        CORNER_ANG[normal.as_tuple(), side_norm.as_tuple()].ang,
        first_size,
        config,
    )

    off_straight_loc = first_corner_loc + normal * (128 * (first_size - 1))
    off_straight_loc += side_norm * (128 * first_size)

    if side_straight > 0:
        make_straight(
            off_straight_loc,
            side_norm,
            side_straight,
            config,
        )

    sec_corner_loc = off_straight_loc + side_norm * side_straight

    make_corner(
        sec_corner_loc,
        CORNER_ANG[side_norm.as_tuple(), (-normal).as_tuple()].ang,
        second_size,
        config,
    )

    if second_straight > 0:
        make_straight(
            sec_corner_loc - normal * (128 * second_size),
            -normal,
            second_straight,
            config,
        )
开发者ID:BenVlodgi,项目名称:BEE2.4,代码行数:104,代码来源:vactubes.py

示例9: res_insert_overlay

# 需要导入模块: from srctools import Vec [as 别名]
# 或者: from srctools.Vec import as_tuple [as 别名]
def res_insert_overlay(inst: Entity, res: Property):
    """Use a template to insert one or more overlays on a surface.

    Options:

    - ID: The template ID. Brushes will be ignored.
    - Replace: old -> new material replacements.
    - Face_pos: The offset of the brush face.
    - Normal: The direction of the brush face.
    - Offset: An offset to move the overlays by.
    """
    (
        temp_id,
        replace,
        face,
        norm,
        offset,
    ) = res.value

    if temp_id[:1] == '$':
        temp_id = inst.fixup[temp_id]

    origin = Vec.from_str(inst['origin'])  # type: Vec
    angles = Vec.from_str(inst['angles', '0 0 0'])

    face_pos = Vec(face).rotate(*angles)
    face_pos += origin
    normal = Vec(norm).rotate(*angles)

    # Don't make offset change the face_pos value..
    origin += offset.copy().rotate_by_str(
        inst['angles', '0 0 0']
    )

    for axis, norm in enumerate(normal):
        # Align to the center of the block grid. The normal direction is
        # already correct.
        if norm == 0:
            face_pos[axis] = face_pos[axis] // 128 * 128 + 64

    try:
        face_id = SOLIDS[face_pos.as_tuple()].face.id
    except KeyError:
        LOGGER.warning(
            'Overlay brush position is not valid: {}',
            face_pos,
        )
        return

    temp = template_brush.import_template(
        temp_id,
        origin,
        angles,
        targetname=inst['targetname', ''],
        force_type=TEMP_TYPES.detail,
    )

    for over in temp.overlay:  # type: Entity
        random.seed('TEMP_OVERLAY_' + over['basisorigin'])
        mat = random.choice(replace.get(
            over['material'],
            (over['material'], ),
        ))
        if mat[:1] == '$':
            mat = inst.fixup[mat]
        if mat.startswith('<') or mat.endswith('>'):
            # Lookup in the style data.
            import vbsp
            LOGGER.info('Tex: {}', vbsp.settings['textures'].keys())
            mat = vbsp.get_tex(mat[1:-1])
        over['material'] = mat
        over['sides'] = str(face_id)

    # Wipe the brushes from the map.
    if temp.detail is not None:
        temp.detail.remove()
        LOGGER.info(
            'Overlay template "{}" could set keep_brushes=0.',
            temp_id,
        )
开发者ID:BenVlodgi,项目名称:BEE2.4,代码行数:82,代码来源:entities.py

示例10: res_make_tag_fizzler

# 需要导入模块: from srctools import Vec [as 别名]
# 或者: from srctools.Vec import as_tuple [as 别名]

#.........这里部分代码省略.........
                # smallest magnitude.
                sign_dir = min(
                    sign_floor_loc - Vec.with_axes(
                        axis,side_min,
                        other_axis, normal,
                    ),
                    sign_floor_loc - Vec.with_axes(
                        axis, side_max,
                        other_axis, normal,
                    ),
                    key=Vec.mag,
                )
            else:
                # Align just based on whether we're in front or behind.
                sign_dir = Vec()
                sign_dir[other_axis] = sign_floor_loc[other_axis] - normal

        sign_angle = math.degrees(
            math.atan2(sign_dir.y, sign_dir.x)
        )
        # Round to nearest 90 degrees
        # Add 45 so the switchover point is at the diagonals
        sign_angle = (sign_angle + 45) // 90 * 90

        # Rotate to fit the instances - south is down
        sign_angle = int(sign_angle + 90) % 360
        if inst_normal.z > 0:
            sign_angle = '0 {} 0'.format(sign_angle)
        elif inst_normal.z < 0:
            # Flip upside-down for ceilings
            sign_angle = '0 {} 180'.format(sign_angle)
    else:
        # On a wall, face upright
        sign_angle = PETI_INST_ANGLE[inst_normal.as_tuple()]

    # If disable_other, we show off signs. Otherwise we don't use that sign.
    blue_sign = blue_sign_on if blue_enabled else blue_sign_off if disable_other else None
    oran_sign = oran_sign_on if oran_enabled else oran_sign_off if disable_other else None

    if blue_sign:
        vmf.create_ent(
            classname='func_instance',
            file=blue_sign,
            targetname=inst['targetname'],
            angles=sign_angle,
            origin=blue_loc.join(' '),
        )

    if oran_sign:
        vmf.create_ent(
            classname='func_instance',
            file=oran_sign,
            targetname=inst['targetname'],
            angles=sign_angle,
            origin=oran_loc.join(' '),
        )

    # Now modify the fizzler...

    # Subtract the sign from the list of connections, but don't go below
    # zero
    fizzler.base_inst.fixup['$connectioncount'] = str(max(
        0,
        srctools.conv_int(fizzler.base_inst.fixup['$connectioncount', '']) - 1
    ))
开发者ID:BenVlodgi,项目名称:BEE2.4,代码行数:69,代码来源:apTag.py

示例11: res_make_catwalk

# 需要导入模块: from srctools import Vec [as 别名]
# 或者: from srctools.Vec import as_tuple [as 别名]

#.........这里部分代码省略.........

    LOGGER.info('Connections: {}', links)
    LOGGER.info('Markers: {}', markers)

    # First loop through all the markers, adding connecting sections
    for marker_name, inst in markers.items():
        mark_item = ITEMS[marker_name]
        mark_item.delete_antlines()
        for conn in list(mark_item.outputs):
            try:
                inst2 = markers[conn.to_item.name]
            except KeyError:
                LOGGER.warning('Catwalk connected to non-catwalk!')

            conn.remove()

            origin1 = Vec.from_str(inst['origin'])
            origin2 = Vec.from_str(inst2['origin'])
            if origin1.x != origin2.x and origin1.y != origin2.y:
                LOGGER.warning('Instances not aligned!')
                continue

            y_dir = origin1.x == origin2.x  # Which way the connection is
            if y_dir:
                dist = abs(origin1.y - origin2.y)
            else:
                dist = abs(origin1.x - origin2.x)
            vert_dist = origin1.z - origin2.z

            if (dist - 128) // 2 < abs(vert_dist):
                # The stairs are 2 long, 1 high. Check there's enough room
                # Subtract the last block though, since that's a corner.
                LOGGER.warning('Not enough room for stairs!')
                continue

            if dist > 128:
                # add straight sections in between
                place_catwalk_connections(vmf, instances, origin1, origin2)

            # Update the lists based on the directions that were set
            conn_lst1 = links[inst]
            conn_lst2 = links[inst2]
            if origin1.x < origin2.x:
                conn_lst1.E = conn_lst2.W = True
            elif origin2.x < origin1.x:
                conn_lst1.W = conn_lst2.E = True

            if origin1.y < origin2.y:
                conn_lst1.N = conn_lst2.S = True
            elif origin2.y < origin1.y:
                conn_lst1.S = conn_lst2.N = True

    for inst, dir_mask in links.items():
        # Set the marker instances based on the attached walkways.
        normal = Vec(0, 0, 1).rotate_by_str(inst['angles'])

        new_type, inst['angles'] = utils.CONN_LOOKUP[dir_mask.as_tuple()]
        inst['file'] = instances[CATWALK_TYPES[new_type]]

        if new_type is utils.CONN_TYPES.side:
            # If the end piece is pointing at a wall, switch the instance.
            if normal.z == 0:
                if normal == dir_mask.conn_dir():
                    inst['file'] = instances['end_wall']
            continue  # We never have normal supports on end pieces
        elif new_type is utils.CONN_TYPES.none:
            # Unconnected catwalks on the wall switch to a special instance.
            # This lets players stand next to a portal surface on the wall.
            if normal.z == 0:
                inst['file'] = instances['single_wall']
                inst['angles'] = INST_ANGLE[normal.as_tuple()]
            else:
                inst.remove()
            continue  # These don't get supports otherwise

        # Add regular supports
        supp = None
        if normal == (0, 0, 1):
            # If in goo, use different supports!
            origin = Vec.from_str(inst['origin'])
            origin.z -= 128
            if brushLoc.POS['world': origin].is_goo:
                supp = instances['support_goo']
            else:
                supp = instances['support_floor']
        elif normal == (0, 0, -1):
            supp = instances['support_ceil']
        else:
            supp = instances['support_wall']

        if supp:
            vmf.create_ent(
                classname='func_instance',
                origin=inst['origin'],
                angles=INST_ANGLE[normal.as_tuple()],
                file=supp,
            )

    LOGGER.info('Finished catwalk generation!')
    return RES_EXHAUSTED
开发者ID:BenVlodgi,项目名称:BEE2.4,代码行数:104,代码来源:catwalks.py

示例12: res_import_template

# 需要导入模块: from srctools import Vec [as 别名]
# 或者: from srctools.Vec import as_tuple [as 别名]

#.........这里部分代码省略.........
                '"{}" is not a valid template!',
                temp_name
            )
        # We don't want an error, just quit.
        return

    if color_var.casefold() == '<editor>':
        # Check traits for the colour it should be.
        traits = instance_traits.get(inst)
        if 'white' in traits:
            force_colour = template_brush.MAT_TYPES.white
        elif 'black' in traits:
            force_colour = template_brush.MAT_TYPES.black
        else:
            LOGGER.warning(
                '"{}": Instance "{}" '
                "isn't one with inherent color!",
                temp_id,
                inst['file'],
            )
    elif color_var:
        color_val = conditions.resolve_value(inst, color_var).casefold()

        if color_val == 'white':
            force_colour = template_brush.MAT_TYPES.white
        elif color_val == 'black':
            force_colour = template_brush.MAT_TYPES.black
    # else: no color var

    if srctools.conv_bool(conditions.resolve_value(inst, invert_var)):
        force_colour = template_brush.TEMP_COLOUR_INVERT[force_colour]
    # else: False value, no invert.

    origin = Vec.from_str(inst['origin'])
    angles = Vec.from_str(inst['angles', '0 0 0'])
    temp_data = template_brush.import_template(
        template,
        origin,
        angles,
        targetname=inst['targetname', ''],
        force_type=force_type,
        visgroup_choose=visgroup_func,
        add_to_map=True,
        additional_visgroups=visgroups,
    )

    if key_block is not None:
        conditions.set_ent_keys(temp_data.detail, inst, key_block)
        br_origin = Vec.from_str(key_block.find_key('keys')['origin'])
        br_origin.localise(origin, angles)
        temp_data.detail['origin'] = br_origin

        move_dir = temp_data.detail['movedir', '']
        if move_dir.startswith('<') and move_dir.endswith('>'):
            move_dir = Vec.from_str(move_dir).rotate(*angles)
            temp_data.detail['movedir'] = move_dir.to_angle()

        for out in outputs:  # type: Output
            out = out.copy()
            out.target = conditions.local_name(inst, out.target)
            temp_data.detail.add_out(out)

        # Add it to the list of ignored brushes, so vbsp.change_brush() doesn't
        # modify it.
        vbsp.IGNORED_BRUSH_ENTS.add(temp_data.detail)

    try:
        # This is the original brush the template is replacing. We fix overlay
        # face IDs, so this brush is replaced by the faces in the template
        # pointing
        # the same way.
        if replace_brush_pos is None:
            raise KeyError  # Not set, raise to jump out of the try block

        pos = Vec(replace_brush_pos).rotate(angles.x, angles.y, angles.z)
        pos += origin
        brush_group = SOLIDS[pos.as_tuple()]
    except KeyError:
        # Not set or solid group doesn't exist, skip..
        pass
    else:
        LOGGER.info('IDS: {}', additional_replace_ids | template.overlay_faces)
        conditions.steal_from_brush(
            temp_data,
            brush_group,
            rem_replace_brush,
            map(int, additional_replace_ids | template.overlay_faces),
            conv_bool(conditions.resolve_value(inst, transfer_overlays), True),
        )

    template_brush.retexture_template(
        temp_data,
        origin,
        inst.fixup,
        replace_tex,
        force_colour,
        force_grid,
        # Don't allow clumping if using custom keyvalues - then it won't be edited.
        no_clumping=key_block is not None,
    )
开发者ID:BenVlodgi,项目名称:BEE2.4,代码行数:104,代码来源:brushes.py

示例13: add_glass_floorbeams

# 需要导入模块: from srctools import Vec [as 别名]
# 或者: from srctools.Vec import as_tuple [as 别名]
def add_glass_floorbeams(vmf: VMF, temp_name: str):
    """Add beams to separate large glass panels.

    The texture is assumed to match plasticwall004a's shape.
    """
    template = template_brush.get_template(temp_name)
    temp_world, temp_detail, temp_over = template.visgrouped()
    try:
        [beam_template] = temp_world + temp_detail  # type: Solid
    except ValueError:
        raise ValueError('Bad Glass Floorbeam template!')

    # Grab the 'end' side, which we move around.
    for side in beam_template.sides:
        if side.normal() == (-1, 0, 0):
            beam_end_face = side
            break
    else:
        raise ValueError('Not aligned to world...')

    separation = vbsp_options.get(int, 'glass_floorbeam_sep') + 1
    separation *= 128

    # First we want to find all the groups of contiguous glass sections.
    # This is a mapping from some glass piece to its group list.
    groups = {}

    for (origin, normal), barr_type in BARRIERS.items():
        # Grating doesn't use it.
        if barr_type is not BarrierType.GLASS:
            continue

        normal = Vec(normal)

        if not normal.z:
            # Not walls.
            continue

        pos = Vec(origin) + normal * 62

        groups[pos.as_tuple()] = [pos]

    # Loop over every pos and check in the +x/y directions for another glass
    # piece. If there, merge the two lists and set every pos in the group to
    # point to the new list.
    # Once done, every unique list = a group.

    for pos_tup in groups.keys():
        pos = Vec(pos_tup)
        for off in ((128, 0, 0), (0, 128, 0)):
            neighbour = (pos + off).as_tuple()
            if neighbour in groups:
                our_group = groups[pos_tup]
                neigh_group = groups[neighbour]
                if our_group is neigh_group:
                    continue

                # Now merge the two lists. We then need to update all dict locs
                # to point to the new list.

                if len(neigh_group) > len(our_group):
                    small_group, large_group = our_group, neigh_group
                else:
                    small_group, large_group = neigh_group, our_group

                large_group.extend(small_group)
                for pos in small_group:
                    groups[pos.as_tuple()] = large_group

    # Remove duplicates objects by using the ID as key..
    groups = list({
        id(group): group
        for group in groups.values()
    }.values())

    # Side -> u, v or None

    for group in groups:

        bbox_min, bbox_max = Vec.bbox(group)
        dimensions = bbox_max - bbox_min
        LOGGER.info('Size = {}', dimensions)

        # Our beams align to the smallest axis.
        if dimensions.y > dimensions.x:
            beam_ax = 'x'
            side_ax = 'y'
            rot = Vec(0, 0, 0)
        else:
            beam_ax = 'y'
            side_ax = 'x'
            rot = Vec(0, 90, 0)

        # Build min, max tuples for each axis in the other direction.
        # This tells us where the beams will be.
        beams = {}  # type: Dict[int, Tuple[int, int]]

        # Add 128 so the first pos isn't a beam.
        offset = bbox_min[side_ax] + 128

#.........这里部分代码省略.........
开发者ID:BenVlodgi,项目名称:BEE2.4,代码行数:103,代码来源:barriers.py

示例14: convert_floor

# 需要导入模块: from srctools import Vec [as 别名]
# 或者: from srctools.Vec import as_tuple [as 别名]
def convert_floor(
    vmf: VMF,
    loc: Vec,
    overlay_ids,
    mats,
    settings,
    signage_loc,
    detail,
    noise_weight,
    noise_func: SimplexNoise,
):
    """Cut out tiles at the specified location."""
    # We pop it, so the face isn't detected by other logic - otherwise it'll
    # be retextured and whatnot, which we don't want.
    try:
        brush = conditions.SOLIDS.pop(loc.as_tuple())
    except KeyError:
        return False  # No tile here!

    if brush.normal == (0, 0, 1):
        # This is a pillar block - there isn't actually tiles here!
        # We need to generate a squarebeams brush to fill this gap.

        brush.face.mat = 'tools/toolsnodraw'  # It won't be visible
        temp_data = template_brush.import_template(
            temp_name=FLOOR_TEMP_PILLAR,
            origin=loc,
        )
        template_brush.retexture_template(
            temp_data,
            loc,
            # Switch to use the configured squarebeams texture
            replace_tex={
                consts.Special.SQUAREBEAMS: random.choice(
                    MATS['squarebeams']
                ),
            }
        )
        return False

    # The new brush IDs overlays need to use
    # NOTE: strings, not ints!
    ant_locs = overlay_ids[str(brush.face.id)] = []

    # Move the floor brush down and switch to the floorbase texture.
    for plane in brush.face.planes:
        plane.z -= FLOOR_DEPTH
    brush.face.mat = random.choice(mats['floorbase'])

    loc.x -= 64
    loc.y -= 64

    for x, y in utils.iter_grid(max_x=4, max_y=4):
        tile_loc = loc + (x * 32 + 16, y * 32 + 16, 0)
        if tile_loc.as_tuple() in signage_loc:
            # Force the tile to be present under signage..
            should_make_tile = True
            rand = 100
            # We don't need to check this again in future!
            signage_loc.remove(tile_loc.as_tuple())
        else:
            # Create a number between 0-100
            rand = 100 * get_noise(tile_loc // 32, noise_func) + 10

            # Adjust based on the noise_weight value, so boundries have more tiles
            rand *= 0.1 + 0.9 * (1 - noise_weight)

            should_make_tile = rand < settings['floor_chance']
            if random.randint(0, 7) == 0:
                # Sometimes there'll be random holes/extra tiles
                should_make_tile = not should_make_tile

        if should_make_tile:
            # Full tile
            tile = make_tile(
                vmf,
                p1=tile_loc - (16, 16, 0),
                p2=tile_loc + (16, 16, -2),
                top_mat=vbsp.get_tex(str(brush.color) + '.floor'),
                bottom_mat='tools/toolsnodraw',
                beam_mat=random.choice(mats['squarebeams']),
            )
            detail.solids.append(tile.solid)
            ant_locs.append(str(tile.top.id))
        elif rand < settings['floor_glue_chance']:
            # 'Glue' tile - this chance should be higher, making these appear
            # bordering the full tiles.
            tile = make_tile(
                vmf,
                p1=tile_loc - (16, 16, 1),
                p2=tile_loc + (16, 16, -2),
                top_mat=random.choice(mats['tile_glue']),
                bottom_mat='tools/toolsnodraw',
                beam_mat=random.choice(mats['squarebeams']),
            )
            detail.solids.append(tile.solid)
        else:
            # No tile at this loc!
            pass

#.........这里部分代码省略.........
开发者ID:BenVlodgi,项目名称:BEE2.4,代码行数:103,代码来源:cutoutTile.py

示例15: parse_map

# 需要导入模块: from srctools import Vec [as 别名]
# 或者: from srctools.Vec import as_tuple [as 别名]
def parse_map(vmf: VMF, voice_attrs: Dict[str, bool]) -> None:
    """Analyse fizzler instances to assign fizzler types.

    Instance traits are required.
    The model instances and brushes will be removed from the map.
    Needs connections to be parsed.
    """

    # Item ID and model skin -> fizzler type
    fizz_types = {}  # type: Dict[Tuple[str, int], FizzlerType]

    for fizz_type in FIZZ_TYPES.values():
        for item_id in fizz_type.item_ids:
            if ':' in item_id:
                item_id, barrier_type = item_id.split(':')
                if barrier_type == 'laserfield':
                    barrier_skin = 2
                elif barrier_type == 'fizzler':
                    barrier_skin = 0
                else:
                    LOGGER.error('Invalid barrier type ({}) for "{}"!', barrier_type, item_id)
                    fizz_types[item_id, 0] = fizz_type
                    fizz_types[item_id, 2] = fizz_type
                    continue
                fizz_types[item_id, barrier_skin] = fizz_type
            else:
                fizz_types[item_id, 0] = fizz_type
                fizz_types[item_id, 2] = fizz_type

    fizz_bases = {}  # type: Dict[str, Entity]
    fizz_models = defaultdict(list)  # type: Dict[str, List[Entity]]

    # Position and normal -> name, for output relays.
    fizz_pos = {}  # type: Dict[Tuple[Tuple[float, float, float], Tuple[float, float, float]], str]

    # First use traits to gather up all the instances.
    for inst in vmf.by_class['func_instance']:
        traits = instance_traits.get(inst)
        if 'fizzler' not in traits:
            continue

        name = inst['targetname']

        if 'fizzler_model' in traits:
            name = name.rsplit('_model', 1)[0]
            fizz_models[name].append(inst)
            inst.remove()
        elif 'fizzler_base' in traits:
            fizz_bases[name] = inst
        else:
            LOGGER.warning('Fizzler "{}" has non-base, non-model instance?', name)
            continue

        origin = Vec.from_str(inst['origin'])
        normal = Vec(z=1).rotate_by_str(inst['angles'])
        fizz_pos[origin.as_tuple(), normal.as_tuple()] = name

    for name, base_inst in fizz_bases.items():
        models = fizz_models[name]
        up_axis = Vec(y=1).rotate_by_str(base_inst['angles'])

        # If upside-down, make it face upright.
        if up_axis == (0, 0, -1):
            up_axis = Vec(z=1)

        base_inst.outputs.clear()

        # Now match the pairs of models to each other.
        # The length axis is the line between them.
        # We don't care about the instances after this, so don't keep track.
        length_axis = Vec(z=1).rotate_by_str(base_inst['angles']).axis()

        emitters = []  # type: List[Tuple[Vec, Vec]]

        model_pairs = {}  # type: Dict[Tuple[float, float], Vec]

        model_skin = models[0].fixup.int('$skin')

        try:
            item_id, item_subtype = instanceLocs.ITEM_FOR_FILE[base_inst['file'].casefold()]
            fizz_type = fizz_types[item_id, model_skin]
        except KeyError:
            LOGGER.warning('Fizzler types: {}', fizz_types.keys())
            raise ValueError('No fizzler type for "{}"!'.format(
                base_inst['file'],
            )) from None

        for attr_name in fizz_type.voice_attrs:
            voice_attrs[attr_name] = True

        for model in models:
            pos = Vec.from_str(model['origin'])
            try:
                other_pos = model_pairs.pop(pos.other_axes(length_axis))
            except KeyError:
                # No other position yet, we need to find that.
                model_pairs[pos.other_axes(length_axis)] = pos
                continue

            min_pos, max_pos = Vec.bbox(pos, other_pos)
#.........这里部分代码省略.........
开发者ID:BenVlodgi,项目名称:BEE2.4,代码行数:103,代码来源:fizzler.py


注:本文中的srctools.Vec.as_tuple方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。