def res_temp_reset_gridded(inst: Entity): """Temporary result - reset gridded state on a surface. Used for antline routers to undo ItemLightStrip's 4x4 texturing. This should be removed after geometry is done. """ pos = Vec(0, 0, -64) pos.localise( Vec.from_str(inst['origin']), Vec.from_str(inst['angles']) ) norm = Vec(z=-1).rotate_by_str(inst['angles']) for axis in 'xyz': # Don't realign things in the normal's axis - # those are already fine. if not norm[axis]: pos[axis] //= 128 pos[axis] *= 128 pos[axis] += 64 brush = SOLIDS.get(pos.as_tuple(), None) if brush is None: return if brush.color is template_brush.MAT_TYPES.white: brush.face.mat = const.WhitePan.WHITE_1x1 else: brush.face.mat = const.BlackPan.BLACK_1
def flag_brush_at_loc(inst, flag): """Checks to see if a wall is present at the given location. - Pos is the position of the brush, where `0 0 0` is the floor-position of the brush. - Dir is the normal the face is pointing. (0 0 -1) is 'up'. - Type defines the type the brush must be: - "Any" requires either a black or white brush. - "None" means that no brush must be present. - "White" requires a portalable surface. - "Black" requires a non-portalable surface. - SetVar defines an instvar which will be given a value of "black", "white" or "none" to allow the result to be reused. - If gridPos is true, the position will be snapped so it aligns with the 128 brushes (Useful with fizzler/light strip items). - RemoveBrush: If set to 1, the brush will be removed if found. Only do this to EmbedFace brushes, since it will remove the other sides as well. """ from conditions import VMF pos = Vec.from_str(flag['pos', '0 0 0']) pos.z -= 64 # Subtract so origin is the floor-position pos = pos.rotate_by_str(inst['angles', '0 0 0']) # Relative to the instance origin pos += Vec.from_str(inst['origin', '0 0 0']) norm = Vec.from_str(flag['dir', '0 0 -1']).rotate_by_str( inst['angles', '0 0 0'] ) if utils.conv_bool(flag['gridpos', '0']): for axis in 'xyz': # Don't realign things in the normal's axis - # those are already fine. if norm[axis] == 0: pos[axis] = pos[axis] // 128 * 128 + 64 result_var = flag['setVar', ''] should_remove = utils.conv_bool(flag['RemoveBrush', False], False) des_type = flag['type', 'any'].casefold() brush = SOLIDS.get(pos.as_tuple(), None) if brush is None or brush.normal != norm: br_type = 'none' else: br_type = str(brush.color) if should_remove: VMF.remove_brush( brush.solid, ) if result_var: inst.fixup[result_var] = br_type if des_type == 'any' and br_type != 'none': return True return des_type == br_type
def flag_brush_at_loc(inst: Entity, flag: Property): """Checks to see if a wall is present at the given location. - Pos is the position of the brush, where `0 0 0` is the floor-position of the brush. - Dir is the normal the face is pointing. (0 0 -1) is 'up'. - Type defines the type the brush must be: - "Any" requires either a black or white brush. - "None" means that no brush must be present. - "White" requires a portalable surface. - "Black" requires a non-portalable surface. - SetVar defines an instvar which will be given a value of "black", "white" or "none" to allow the result to be reused. - If gridPos is true, the position will be snapped so it aligns with the 128 brushes (Useful with fizzler/light strip items). - RemoveBrush: If set to 1, the brush will be removed if found. Only do this to EmbedFace brushes, since it will remove the other sides as well. """ from conditions import VMF pos = Vec.from_str(flag['pos', '0 0 0']) pos.z -= 64 # Subtract so origin is the floor-position pos = pos.rotate_by_str(inst['angles', '0 0 0']) # Relative to the instance origin pos += Vec.from_str(inst['origin', '0 0 0']) norm = flag['dir', None] if norm is not None: norm = Vec.from_str(norm).rotate_by_str(inst['angles', '0 0 0'], ) if srctools.conv_bool(flag['gridpos', '0']) and norm is not None: for axis in 'xyz': # Don't realign things in the normal's axis - # those are already fine. if norm[axis] == 0: pos[axis] = pos[axis] // 128 * 128 + 64 result_var = flag['setVar', ''] should_remove = srctools.conv_bool(flag['RemoveBrush', False], False) des_type = flag['type', 'any'].casefold() brush = SOLIDS.get(pos.as_tuple(), None) if brush is None or (norm is not None and abs(brush.normal) != abs(norm)): br_type = 'none' else: br_type = str(brush.color) if should_remove: VMF.remove_brush(brush.solid, ) if result_var: inst.fixup[result_var] = br_type if des_type == 'any' and br_type != 'none': return True return des_type == br_type
def res_set_texture(inst: Entity, res: Property): """Set the brush face at a location to a particular texture. pos is the position, relative to the instance (0 0 0 is the floor-surface). dir is the normal of the texture. If gridPos is true, the position will be snapped so it aligns with the 128 brushes (Useful with fizzler/light strip items). tex is the texture used. If tex begins and ends with '<>', certain textures will be used based on style: - '<delete>' will remove the brush entirely (it should be hollow). Caution should be used to ensure no leaks occur. - '<special>' the brush will be given a special texture like angled and flip panels. - '<white>' and '<black>' will use the regular textures for the given color. - '<white-2x2>', '<white-4x4>', '<black-2x2>', '<black-4x4'> will use the given wall-sizes. If on floors or ceilings these always use 4x4. - '<2x2>' or '<4x4>' will force to the given wall-size, keeping color. - '<special-white>' and '<special-black>' will use a special texture of the given color. If tex begins and ends with '[]', it is an option in the 'Textures' list. These are composed of a group and texture, separated by '.'. 'white.wall' are the white wall textures; 'special.goo' is the goo texture. If 'template' is set, the template should be an axis aligned cube. This will be rotated by the instance angles, and then the face with the same orientation will be applied to the face (with the rotation and texture). """ import vbsp pos = Vec.from_str(res['pos', '0 0 0']) pos.z -= 64 # Subtract so origin is the floor-position pos = pos.rotate_by_str(inst['angles', '0 0 0']) # Relative to the instance origin pos += Vec.from_str(inst['origin', '0 0 0']) norm = Vec.from_str(res['dir', '0 0 -1']).rotate_by_str(inst['angles', '0 0 0']) if srctools.conv_bool(res['gridpos', '0']): for axis in 'xyz': # Don't realign things in the normal's axis - # those are already fine. if not norm[axis]: pos[axis] //= 128 pos[axis] *= 128 pos[axis] += 64 brush = SOLIDS.get(pos.as_tuple(), None) ':type brush: solidGroup' if not brush or brush.normal != norm: return face_to_mod = brush.face # type: Side # Don't allow this to get overwritten later. vbsp.IGNORED_FACES.add(face_to_mod) temp = res['template', None] if temp: # Grab the scaling template and apply it to the brush. template_brush.get_scaling_template(temp).rotate( Vec.from_str(inst['angles']), Vec.from_str(inst['origin']), ).apply(face_to_mod) return tex = res['tex'] if tex.startswith('[') and tex.endswith(']'): face_to_mod.mat = vbsp.get_tex(tex[1:-1]) elif tex.startswith('<') and tex.endswith('>'): # Special texture names! tex = tex[1:-1].casefold() if tex == 'delete': vbsp.VMF.remove_brush(brush) return if tex == 'white': face_to_mod.mat = 'tile/white_wall_tile003a' elif tex == 'black': face_to_mod.mat = 'metal/black_wall_metal_002c' if tex == 'black' or tex == 'white': # For these two, run the regular logic to apply textures # correctly. vbsp.alter_mat( face_to_mod, vbsp.face_seed(face_to_mod), vbsp_options.get(bool, 'tile_texture_lock'), ) if tex == 'special': vbsp.set_special_mat(face_to_mod, str(brush.color)) elif tex == 'special-white': vbsp.set_special_mat(face_to_mod, 'white') return elif tex == 'special-black': vbsp.set_special_mat(brush.face, 'black') # Do <4x4>, <white-2x4>, etc color = str(brush.color) if tex.startswith('black') or tex.endswith('white'): # Override the color used for 2x2/4x4 brushes color = tex[:5] if tex.endswith('2x2') or tex.endswith('4x4'): # 4x4 and 2x2 instructions are ignored on floors and ceilings. orient = vbsp.get_face_orient(face_to_mod) if orient == vbsp.ORIENT.wall: face_to_mod.mat = vbsp.get_tex(color + '.' + tex[-3:]) else: face_to_mod.mat = vbsp.get_tex(color + '.' + str(orient)) else: face_to_mod.mat = tex
def res_set_texture(inst, res): """Set the brush face at a location to a particular texture. pos is the position, relative to the instance (0 0 0 is the floor-surface). dir is the normal of the texture. If gridPos is true, the position will be snapped so it aligns with the 128 brushes (Useful with fizzler/light strip items). tex is the texture used. If tex begins and ends with '<>', certain textures will be used based on style: - If tex is '<special>', the brush will be given a special texture like angled and clear panels. - '<white>' and '<black>' will use the regular textures for the given color. - '<white-2x2>', '<white-4x4>', '<black-2x2>', '<black-4x4'> will use the given wall-sizes. If on floors or ceilings these always use 4x4. - '<2x2>' or '<4x4>' will force to the given wall-size, keeping color. - '<special-white>' and '<special-black>' will use a special texture of the given color. If tex begins and ends with '[]', it is an option in the 'Textures' list. These are composed of a group and texture, separated by '.'. 'white.wall' are the white wall textures; 'special.goo' is the goo texture. """ import vbsp pos = Vec.from_str(res['pos', '0 0 0']) pos.z -= 64 # Subtract so origin is the floor-position pos = pos.rotate_by_str(inst['angles', '0 0 0']) # Relative to the instance origin pos += Vec.from_str(inst['origin', '0 0 0']) norm = Vec.from_str(res['dir', '0 0 -1']).rotate_by_str( inst['angles', '0 0 0'] ) if utils.conv_bool(res['gridpos', '0']): for axis in 'xyz': # Don't realign things in the normal's axis - # those are already fine. if not norm[axis]: pos[axis] //= 128 pos[axis] *= 128 pos[axis] += 64 brush = SOLIDS.get(pos.as_tuple(), None) ':type brush: solidGroup' if not brush or brush.normal != norm: return tex = res['tex'] if tex.startswith('[') and tex.endswith(']'): brush.face.mat = vbsp.get_tex(tex[1:-1]) brush.face.mat = tex elif tex.startswith('<') and tex.endswith('>'): # Special texture names! tex = tex[1:-1].casefold() if tex == 'white': brush.face.mat = 'tile/white_wall_tile003a' elif tex == 'black': brush.face.mat = 'metal/black_wall_metal_002c' if tex == 'black' or tex == 'white': # For these two, run the regular logic to apply textures # correctly. vbsp.alter_mat( brush.face, vbsp.face_seed(brush.face), vbsp.get_bool_opt('tile_texture_lock', True), ) if tex == 'special': vbsp.set_special_mat(brush.face, str(brush.color)) elif tex == 'special-white': vbsp.set_special_mat(brush.face, 'white') return elif tex == 'special-black': vbsp.set_special_mat(brush.face, 'black') # Do <4x4>, <white-2x4>, etc color = str(brush.color) if tex.startswith('black') or tex.endswith('white'): # Override the color used for 2x2/4x4 brushes color = tex[:5] if tex.endswith('2x2') or tex.endswith('4x4'): # 4x4 and 2x2 instructions are ignored on floors and ceilings. orient = vbsp.get_face_orient(brush.face) if orient == vbsp.ORIENT.wall: brush.face.mat = vbsp.get_tex( color + '.' + tex[-3:] ) else: brush.face.mat = vbsp.get_tex( color + '.' + str(orient) ) else: brush.face.mat = tex # Don't allow this to get overwritten later. vbsp.IGNORED_FACES.add(brush.face)
def flag_brush_at_loc(vmf: VMF, inst: Entity, flag: Property): """Checks to see if a wall is present at the given location. - `Pos` is the position of the brush, where `0 0 0` is the floor-position of the brush. - `Dir` is the normal the face is pointing. `(0 0 -1)` is up. - `Type` defines the type the brush must be: - `Any` requires either a black or white brush. - `None` means that no brush must be present. - `White` requires a portalable surface. - `Black` requires a non-portalable surface. - `SetVar` defines an instvar which will be given a value of `black`, `white` or `none` to allow the result to be reused. - If `gridPos` is true, the position will be snapped so it aligns with the 128 grid (Useful with fizzler/light strip items). - `RemoveBrush`: If set to `1`, the brush will be removed if found. Only do this to `EmbedFace` brushes, since it will remove the other sides as well. """ pos = Vec.from_str(flag['pos', '0 0 0']) pos.z -= 64 # Subtract so origin is the floor-position pos = pos.rotate_by_str(inst['angles', '0 0 0']) # Relative to the instance origin pos += Vec.from_str(inst['origin', '0 0 0']) norm = flag['dir', None] if norm is not None: norm = Vec.from_str(norm).rotate_by_str( inst['angles', '0 0 0'], ) if srctools.conv_bool(flag['gridpos', '0']) and norm is not None: for axis in 'xyz': # Don't realign things in the normal's axis - # those are already fine. if norm[axis] == 0: pos[axis] = pos[axis] // 128 * 128 + 64 result_var = flag['setVar', ''] should_remove = srctools.conv_bool(flag['RemoveBrush', False], False) des_type = flag['type', 'any'].casefold() brush = SOLIDS.get(pos.as_tuple(), None) if brush is None or (norm is not None and abs(brush.normal) != abs(norm)): br_type = 'none' else: br_type = str(brush.color) if should_remove: vmf.remove_brush( brush.solid, ) if result_var: inst.fixup[result_var] = br_type if des_type == 'any' and br_type != 'none': return True return des_type == br_type
def res_set_texture(inst: Entity, res: Property): """Set the brush face at a location to a particular texture. pos is the position, relative to the instance (0 0 0 is the floor-surface). dir is the normal of the texture. If gridPos is true, the position will be snapped so it aligns with the 128 brushes (Useful with fizzler/light strip items). tex is the texture used. If tex begins and ends with `<>`, certain textures will be used based on style: - `<delete>` will remove the brush entirely (it should be hollow). Caution should be used to ensure no leaks occur. - `<special>` the brush will be given a special texture like angled and flip panels. - `<white>` and `<black>` will use the regular textures for the given color. - `<white-2x2>`, `<white-4x4>`, `<black-2x2>`, `<black-4x4>` will use the given wall-sizes. If on floors or ceilings these always use 4x4. - `<2x2>` or `<4x4>` will force to the given wall-size, keeping color. - `<special-white>` and `<special-black>` will use a special texture of the given color. If tex begins and ends with `[]`, it is an option in the `Textures` list. These are composed of a group and texture, separated by `.`. `white.wall` are the white wall textures; `special.goo` is the goo texture. If `template` is set, the template should be an axis aligned cube. This will be rotated by the instance angles, and then the face with the same orientation will be applied to the face (with the rotation and texture). """ import vbsp pos = Vec.from_str(res['pos', '0 0 0']) pos.z -= 64 # Subtract so origin is the floor-position pos = pos.rotate_by_str(inst['angles', '0 0 0']) # Relative to the instance origin pos += Vec.from_str(inst['origin', '0 0 0']) norm = Vec.from_str(res['dir', '0 0 -1']).rotate_by_str( inst['angles', '0 0 0'] ) if srctools.conv_bool(res['gridpos', '0']): for axis in 'xyz': # Don't realign things in the normal's axis - # those are already fine. if not norm[axis]: pos[axis] //= 128 pos[axis] *= 128 pos[axis] += 64 brush = SOLIDS.get(pos.as_tuple(), None) if not brush or brush.normal != norm: return face_to_mod = brush.face # type: Side # Don't allow this to get overwritten later. vbsp.IGNORED_FACES.add(face_to_mod) temp = res['template', None] if temp: # Grab the scaling template and apply it to the brush. template_brush.get_scaling_template(temp).rotate( Vec.from_str(inst['angles']), Vec.from_str(inst['origin']), ).apply(face_to_mod) return tex = res['tex'] if tex.startswith('[') and tex.endswith(']'): face_to_mod.mat = vbsp.get_tex(tex[1:-1]) elif tex.startswith('<') and tex.endswith('>'): # Special texture names! tex = tex[1:-1].casefold() if tex == 'delete': vbsp.VMF.remove_brush(brush) return if tex == 'white': face_to_mod.mat = 'tile/white_wall_tile003a' elif tex == 'black': face_to_mod.mat = 'metal/black_wall_metal_002c' if tex == 'black' or tex == 'white': # For these two, run the regular logic to apply textures # correctly. vbsp.alter_mat( face_to_mod, vbsp.face_seed(face_to_mod), vbsp_options.get(bool, 'tile_texture_lock'), ) if tex == 'special': vbsp.set_special_mat(face_to_mod, str(brush.color)) elif tex == 'special-white': vbsp.set_special_mat(face_to_mod, 'white') return elif tex == 'special-black': vbsp.set_special_mat(brush.face, 'black') # Do <4x4>, <white-2x4>, etc color = str(brush.color) if tex.startswith('black') or tex.endswith('white'): # Override the color used for 2x2/4x4 brushes color = tex[:5] if tex.endswith('2x2') or tex.endswith('4x4'): # 4x4 and 2x2 instructions are ignored on floors and ceilings. orient = vbsp.get_face_orient(face_to_mod) if orient == vbsp.ORIENT.wall: face_to_mod.mat = vbsp.get_tex( color + '.' + tex[-3:] ) else: face_to_mod.mat = vbsp.get_tex( color + '.' + str(orient) ) else: face_to_mod.mat = tex