本文整理汇总了Python中srctools.Vec类的典型用法代码示例。如果您正苦于以下问题:Python Vec类的具体用法?Python Vec怎么用?Python Vec使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了Vec类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。
示例1: find_glass_items
def find_glass_items(config, vmf: VMF) -> Iterator[Tuple[str, Vec, Vec, Vec, dict]]:
"""Find the bounding boxes for all the glass items matching a config.
This yields (targetname, min, max, normal, config) tuples.
"""
# targetname -> min, max, normal, config
glass_items = {}
for inst in vmf.by_class['func_instance']: # type: Entity
try:
conf = config[inst['file'].casefold()]
except KeyError:
continue
targ = inst['targetname']
norm = Vec(x=1).rotate_by_str(inst['angles'])
origin = Vec.from_str(inst['origin']) - 64 * norm
try:
bbox_min, bbox_max, group_norm, group_conf = glass_items[targ]
except KeyError:
# First of this group..
bbox_min, bbox_max = origin.copy(), origin.copy()
group_norm = norm.copy()
glass_items[targ] = bbox_min, bbox_max, group_norm, conf
else:
bbox_min.min(origin)
bbox_max.max(origin)
assert group_norm == norm, '"{}" is inconsistently rotated!'.format(targ)
assert group_conf is conf, '"{}" has multiple configs!'.format(targ)
inst.remove()
for targ, (bbox_min, bbox_max, norm, conf) in glass_items.items():
yield targ, bbox_min, bbox_max, norm, conf
示例2: res_rand_vec
def res_rand_vec(inst: Entity, res: Property) -> None:
"""A modification to RandomNum which generates a random vector instead.
'decimal', 'seed' and 'ResultVar' work like RandomNum. min/max x/y/z
are for each section. If the min and max are equal that number will be used
instead.
"""
is_float = srctools.conv_bool(res['decimal'])
var = res['resultvar', '$random']
set_random_seed(inst, 'e' + res['seed', 'random'])
if is_float:
func = random.uniform
else:
func = random.randint
value = Vec()
for axis in 'xyz':
max_val = srctools.conv_float(res['max_' + axis, 0.0])
min_val = srctools.conv_float(res['min_' + axis, 0.0])
if min_val == max_val:
value[axis] = min_val
else:
value[axis] = func(min_val, max_val)
inst.fixup[var] = value.join(' ')
示例3: res_replace_instance
def res_replace_instance(inst: Entity, res: Property):
"""Replace an instance with another entity.
`keys` and `localkeys` defines the new keyvalues used.
`targetname` and `angles` are preset, and `origin` will be used to offset
the given amount from the current location.
If `keep_instance` is true, the instance entity will be kept instead of
removed.
"""
import vbsp
origin = Vec.from_str(inst['origin'])
angles = inst['angles']
if not srctools.conv_bool(res['keep_instance', '0'], False):
inst.remove() # Do this first to free the ent ID, so the new ent has
# the same one.
# We copy to allow us to still access the $fixups and other values.
new_ent = inst.copy(des_id=inst.id)
new_ent.clear_keys()
# Ensure there's a classname, just in case.
new_ent['classname'] = 'info_null'
vbsp.VMF.add_ent(new_ent)
conditions.set_ent_keys(new_ent, inst, res)
origin += Vec.from_str(new_ent['origin']).rotate_by_str(angles)
new_ent['origin'] = origin
new_ent['angles'] = angles
new_ent['targetname'] = inst['targetname']
示例4: res_glass_hole
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()
示例5: pose
def pose(f, rot):
global FRAME
# Calculate the piston's rotation.
# First find the real position of the piston hinge.
hinge_pos = Vec(-43, 0, 10.5)
hinge_pos.x -= 64
hinge_pos.rotate(float(rot), 0, 0)
hinge_pos.x += 64
# Where we want the end of the piston to be.
anchor_point = Vec(z=-96, x=rot*1.5 + 96)
piston_off = hinge_pos - anchor_point
print(piston_off)
piston_rot = math.degrees(math.atan2(piston_off.z, -piston_off.x))
f.write(frame_temp.format(
time=FRAME,
rot=-round(math.radians(rot), 6),
# Cancel the effect of rot on pist_rot
pist_rot=round(math.radians((piston_rot + rot) % 360), 6),
len=-piston_off.mag(),
marker=Vec(z=anchor_point.z, y=-anchor_point.x),
))
FRAME += 1
示例6: _texture_fit
def _texture_fit(
self,
side: Side,
tex_size: float,
field_length: float,
fizz: Fizzler,
neg: Vec,
pos: Vec,
is_laserfield=False,
) -> None:
"""Calculate the texture offsets required for fitting a texture."""
if side.vaxis.vec() != -fizz.up_axis:
# Rotate it
rot_angle = side.normal().rotation_around()
for _ in range(4):
side.uaxis = side.uaxis.rotate(rot_angle)
side.vaxis = side.vaxis.rotate(rot_angle)
if side.vaxis.vec() == -fizz.up_axis:
break
else:
LOGGER.warning("Can't fix rotation for {} -> {}", side.vaxis, fizz.up_axis)
side.uaxis.offset = -(tex_size / field_length) * neg.dot(side.uaxis.vec())
side.vaxis.offset = -(tex_size / 128) * neg.dot(side.vaxis.vec())
# The above fits it correctly, except it's vertically half-offset.
# For laserfields that's what we want, for fizzlers we want it normal.
if not is_laserfield:
side.vaxis.offset += tex_size / 2
side.uaxis.scale = field_length / tex_size
side.vaxis.scale = 128 / tex_size
side.uaxis.offset %= tex_size
side.vaxis.offset %= tex_size
示例7: res_sendificator
def res_sendificator(vmf: VMF, inst: Entity):
"""Implement Sendificators."""
# For our version, we know which sendtor connects to what laser,
# so we can couple the logic together (avoiding @sendtor_mutex).
sendtor_name = inst['targetname']
sendtor = connections.ITEMS[sendtor_name]
sendtor.enable_cmd += (Output(
'',
'@{}_las_relay_*'.format(sendtor_name),
'Trigger',
delay=0.01,
), )
for ind, conn in enumerate(list(sendtor.outputs), start=1):
las_item = conn.to_item
conn.remove()
try:
targ_offset, targ_normal = SENDTOR_TARGETS[las_item.name]
except KeyError:
LOGGER.warning('"{}" is not a Sendificator target!', las_item.name)
continue
angles = Vec.from_str(las_item.inst['angles'])
targ_offset = targ_offset.copy()
targ_normal = targ_normal.copy().rotate(*angles)
targ_offset.localise(
Vec.from_str(las_item.inst['origin']),
angles,
)
relay_name = '@{}_las_relay_{}'.format(sendtor_name, ind)
relay = vmf.create_ent(
'logic_relay',
targetname=relay_name,
origin=targ_offset,
angles=targ_normal.to_angle(),
)
relay.add_out(
Output('OnTrigger', '!self', 'RunScriptCode', '::sendtor_source <- self;'),
Output('OnTrigger', '@sendtor_fire', 'Trigger'),
)
if not las_item.inputs:
# No other inputs, make it on always. PeTI automatically turns
# it off when inputs are connected, which is annoying.
las_item.inst.fixup['$start_enabled'] = '1'
is_on = True
else:
is_on = las_item.inst.fixup.bool('$start_enabled')
relay['StartDisabled'] = not is_on
las_item.enable_cmd += (Output('', relay_name, 'Enable'),)
las_item.disable_cmd += (Output('', relay_name, 'Disable'),)
LOGGER.info('Relay: {}', relay)
示例8: make_straight
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,
)
示例9: res_unst_scaffold_setup
def res_unst_scaffold_setup(res: Property):
group = res['group', 'DEFAULT_GROUP']
if group not in SCAFFOLD_CONFIGS:
# Store our values in the CONFIGS dictionary
targ_inst, links = SCAFFOLD_CONFIGS[group] = {}, {}
else:
# Grab the already-filled values, and add to them
targ_inst, links = SCAFFOLD_CONFIGS[group]
for block in res.find_all("Instance"):
conf = {
# If set, adjusts the offset appropriately
'is_piston': srctools.conv_bool(block['isPiston', '0']),
'rotate_logic': srctools.conv_bool(block['AlterAng', '1'], True),
'off_floor': Vec.from_str(block['FloorOff', '0 0 0']),
'off_wall': Vec.from_str(block['WallOff', '0 0 0']),
'logic_start': block['startlogic', ''],
'logic_end': block['endLogic', ''],
'logic_mid': block['midLogic', ''],
'logic_start_rev': block['StartLogicRev', None],
'logic_end_rev': block['EndLogicRev', None],
'logic_mid_rev': block['EndLogicRev', None],
'inst_wall': block['wallInst', ''],
'inst_floor': block['floorInst', ''],
'inst_offset': block['offsetInst', None],
# Specially rotated to face the next track!
'inst_end': block['endInst', None],
}
for logic_type in ('logic_start', 'logic_mid', 'logic_end'):
if conf[logic_type + '_rev'] is None:
conf[logic_type + '_rev'] = conf[logic_type]
for inst in instanceLocs.resolve(block['file']):
targ_inst[inst] = conf
# We need to provide vars to link the tracks and beams.
for block in res.find_all('LinkEnt'):
# The name for this set of entities.
# It must be a '@' name, or the name will be fixed-up incorrectly!
loc_name = block['name']
if not loc_name.startswith('@'):
loc_name = '@' + loc_name
links[block['nameVar']] = {
'name': loc_name,
# The next entity (not set in end logic)
'next': block['nextVar'],
# A '*' name to reference all the ents (set on the start logic)
'all': block['allVar', None],
}
return group # We look up the group name to find the values.
示例10: flag_blockpos_type
def flag_blockpos_type(inst: Entity, flag: Property):
"""Determine the type of a grid position.
If the value is single value, that should be the type.
Otherwise, the value should be a block with 'offset' and 'type' values.
The offset is in block increments, with 0 0 0 equal to the mounting surface.
If 'offset2' is also provided, all positions in the bounding box will
be checked.
The type should be a space-seperated list of locations:
* `VOID` (Outside the map)
* `SOLID` (Full wall cube)
* `EMBED` (Hollow wall cube)
* `AIR` (Inside the map, may be occupied by items)
* `OCCUPIED` (Known to be occupied by items)
* `PIT` (Bottomless pits, any)
* `PIT_SINGLE` (one-high)
* `PIT_TOP`
* `PIT_MID`
* `PIT_BOTTOM`
* `GOO`
* `GOO_SINGLE` (one-deep goo)
* `GOO_TOP` (goo surface)
* `GOO_MID`
* `GOO_BOTTOM` (floor)
"""
pos2 = None
if flag.has_children():
pos1 = resolve_offset(inst, flag['offset', '0 0 0'], scale=128, zoff=-128)
types = flag['type'].split()
if 'offset2' in flag:
pos2 = resolve_offset(inst, flag.value, scale=128, zoff=-128)
else:
types = flag.value.split()
pos1 = Vec()
if pos2 is not None:
bbox = Vec.iter_grid(*Vec.bbox(pos1, pos2), stride=128)
else:
bbox = [pos1]
for pos in bbox:
block = brushLoc.POS['world': pos]
for block_type in types:
try:
allowed = brushLoc.BLOCK_LOOKUP[block_type.casefold()]
except KeyError:
raise ValueError('"{}" is not a valid block type!'.format(block_type))
if block in allowed:
break # To next position
else:
return False # Didn't match any in this list.
return True # Matched all positions.
示例11: res_camera_setup
def res_camera_setup(res: Property):
return {
'cam_off': Vec.from_str(res['CamOff', '']),
'yaw_off': Vec.from_str(res['YawOff', '']),
'pitch_off': Vec.from_str(res['PitchOff', '']),
'yaw_inst': instanceLocs.resolve_one(res['yawInst', '']),
'pitch_inst': instanceLocs.resolve_one(res['pitchInst', '']),
'yaw_range': srctools.conv_int(res['YawRange', ''], 90),
'pitch_range': srctools.conv_int(res['YawRange', ''], 90),
}
示例12: res_make_funnel_light
def res_make_funnel_light(inst: Entity):
"""Place a light for Funnel items."""
oran_on = inst.fixup.bool('$start_reversed')
need_blue = need_oran = False
name = ''
if inst.fixup['$connectioncount_polarity'] != '0':
import vbsp
if not vbsp.settings['style_vars']['funnelallowswitchedlights']:
# Allow disabling adding switchable lights.
return
name = conditions.local_name(inst, 'light')
need_blue = need_oran = True
else:
if oran_on:
need_oran = True
else:
need_blue = True
loc = Vec(0, 0, -56)
loc.localise(Vec.from_str(inst['origin']), Vec.from_str(inst['angles']))
if need_blue:
inst.map.create_ent(
classname='light',
targetname=name + '_b' if name else '',
spawnflags=int(oran_on), # 1 = Initially Dark
origin=loc,
_light='50 120 250 50',
_lightHDR='-1 -1 -1 1',
_lightscaleHDR=2,
_fifty_percent_distance=48,
_zero_percent_distance=96,
_hardfalloff=1,
_distance=0,
style=0,
)
if need_oran:
inst.map.create_ent(
classname='light',
targetname=name + '_o' if name else '',
spawnflags=int(not oran_on),
origin=loc,
_light='250 120 50 50',
_lightHDR='-1 -1 -1 1',
_lightscaleHDR=2,
_fifty_percent_distance=48,
_zero_percent_distance=96,
_hardfalloff=1,
_distance=0,
style=0,
)
示例13: _calc_fizz_angles
def _calc_fizz_angles() -> None:
"""Generate FIZZ_ANGLES."""
it = itertools.product('xyz', (-1, 1), 'xyz', (-1, 1))
for norm_axis, norm_mag, roll_axis, roll_mag in it:
if norm_axis == roll_axis:
# They can't both be the same...
continue
norm = Vec.with_axes(norm_axis, norm_mag)
roll = Vec.with_axes(roll_axis, roll_mag)
# Norm is Z, roll is X, we want y.
angle = roll.to_angle_roll(norm)
up_dir = norm.cross(roll)
FIZZ_ANGLES[norm.as_tuple(), up_dir.as_tuple()] = angle
示例14: res_monitor
def res_monitor(inst: Entity, res: Property) -> None:
"""Result for the monitor component.
"""
import vbsp
(
break_inst,
bullseye_name,
bullseye_loc,
bullseye_parent,
) = res.value
ALL_MONITORS.append(Monitor(inst))
has_laser = vbsp.settings['has_attr']['laser']
# Allow turrets if the monitor is setup to allow it, and the actor should
# be shot.
needs_turret = bullseye_name and vbsp_options.get(bool, 'voice_studio_should_shoot')
inst.fixup['$is_breakable'] = has_laser or needs_turret
# We need to generate an ai_relationship, which makes turrets hate
# a bullseye.
if needs_turret:
loc = Vec(bullseye_loc)
loc.localise(
Vec.from_str(inst['origin']),
Vec.from_str(inst['angles']),
)
bullseye_name = local_name(inst, bullseye_name)
inst.map.create_ent(
classname='npc_bullseye',
targetname=bullseye_name,
parentname=local_name(inst, bullseye_parent),
spawnflags=221186, # Non-solid, invisible, etc..
origin=loc,
)
relation = inst.map.create_ent(
classname='ai_relationship',
targetname='@monitor_turr_hate',
spawnflags=2, # Notify turrets about monitor locations
disposition=1, # Hate
origin=loc,
subject='npc_portal_turret_floor',
target=bullseye_name,
)
MONITOR_RELATIONSHIP_ENTS.append(relation)
示例15: get_config
def get_config(
node: item_chain.Node,
) -> Tuple[str, Vec]:
"""Compute the config values for a node."""
orient = (
'floor' if
Vec(0, 0, 1).rotate_by_str(node.inst['angles']) == (0, 0, 1)
else 'wall'
)
# Find the offset used for the platform.
offset = (node.conf['off_' + orient]).copy() # type: Vec
if node.conf['is_piston']:
# Adjust based on the piston position
offset.z += 128 * srctools.conv_int(
node.inst.fixup[
'$top_level' if
node.inst.fixup[
'$start_up'] == '1'
else '$bottom_level'
]
)
offset.rotate_by_str(node.inst['angles'])
offset += Vec.from_str(node.inst['origin'])
return orient, offset