def wcs_teleport_command(command_info, player:convert_userid_to_player, x:float, y:float, z:float): if player is None: return location = Vector(x, y, z) origin = player.origin angles = QAngle(*player.get_property_vector('m_angAbsRotation')) forward = Vector() right = Vector() up = Vector() angles.get_angle_vectors(forward, right, up) forward.normalize() forward *= 10 playerinfo = player.playerinfo mins, maxs = playerinfo.mins, playerinfo.maxs players = TraceFilterSimple(PlayerIter()) for _ in range(100): ray = Ray(location, location, mins, maxs) trace = GameTrace() engine_trace.trace_ray(ray, ContentMasks.PLAYER_SOLID, players, trace) if not trace.did_hit(): player.teleport(origin=location) break location -= forward if location.get_distance(origin) <= 10.0: break
def is_in_solid( self, mask=ContentMasks.ALL, generator=None): """Return whether or not the entity is in solid. :param ContentMasks mask: Contents the ray can possibly collide with. :param generator: A callable that returns an iterable which contains :class:`BaseEntity` instances that are ignored by the ray. :rtype: bool """ # Get the entity's origin origin = self.origin # Get a Ray object of the entity physic box ray = Ray(origin, origin, self.mins, self.maxs) # Get a new GameTrace instance trace = GameTrace() # Do the trace if generator is None: # No need to trace against anything but the world if we are going # to filter out everything regardless. engine_trace.clip_ray_to_entity( ray, mask, BaseEntity(WORLD_ENTITY_INDEX), trace ) else: engine_trace.trace_ray(ray, mask, TraceFilterSimple( generator()), trace) # Return whether or not the trace did hit return trace.did_hit()
def _find_floor(self, origin): if origin is None: origin = self.origin end_trace_vec = origin + Vector(0, 0, -1) * MAX_TRACE_LENGTH trace = GameTrace() engine_trace.trace_ray(Ray(origin, end_trace_vec), ContentMasks.ALL, TraceFilterSimple(), trace) if not trace.did_hit(): return None return trace.end_position
def is_in_solid( self, mask=ContentMasks.ALL, generator=BaseEntityGenerator): """Return whether or not the entity is in solid.""" # Get a Ray object of the entity physic box ray = Ray(self.origin, self.origin, self.mins, self.maxs) # Get a new GameTrace instance trace = GameTrace() # Do the trace engine_trace.trace_ray(ray, mask, TraceFilterSimple( [entity.index for entity in generator()]), trace) # Return whether or not the trace did hit return trace.did_hit()
def is_player_stuck(player_index, origin): '''Return whether or not the given player is stuck in solid.''' # Get the player's PlayerInfo instance... player_info = playerinfo_from_index(player_index) # Get the player's origin... #origin = player_info.origin # Get a Ray object based on the player physic box... ray = Ray(origin, origin, player_info.mins, player_info.maxs) # Get a new GameTrace instance... trace = GameTrace() # Do the trace... engine_trace.trace_ray(ray, ContentMasks.PLAYER_SOLID, TraceFilterSimple(PlayerIter()), trace) # Return whether or not the trace did hit... return trace.did_hit()
def is_in_solid( self, mask=ContentMasks.ALL, generator=BaseEntityGenerator): """Return whether or not the entity is in solid. :param ContentMasks mask: Contents the ray can possibly collide with. :param generator: A callable that returns an iterable which contains :class:`BaseEntity` instances that are ignored by the ray. :rtype: bool """ # Get a Ray object of the entity physic box ray = Ray(self.origin, self.origin, self.mins, self.maxs) # Get a new GameTrace instance trace = GameTrace() # Do the trace engine_trace.trace_ray(ray, mask, TraceFilterSimple( generator()), trace) # Return whether or not the trace did hit return trace.did_hit()
def on_take_damage_alive_pre(stack_data): """Creates a FloatingNumber when a player takes damage.""" # Get the Player instance of the victim. player_v = player_instances[index_from_pointer(stack_data[0])] # Get the CTakeDamageInfo instance. info = TakeDamageInfo._obj(stack_data[1]) # Get the index of the entity that caused the damage. index_a = info.attacker # Did the player take damage from the world? if index_a == 0: # Are damage numbers disabled for world damage (world_damage set to 0)? if not world_damage.get_int(): return number_origin = player_v.get_number_origin() unique_data = [] for player in player_instances.values(): # There's no need for bots to see the FloatingNumber. if player.is_bot(): continue # Is the player not looking at the position where the # FloatingNumber is going to spawn? if not player.is_in_fov(target=number_origin): continue distance = number_origin.get_distance(player.origin) # Add this player's unique data to the list. unique_data.append({ 'angle': player.view_angle, 'size': 10 + distance * DISTANCE_MULTIPLIER, 'recipient': player.userid }) # Will no one be able to see this FloatingNumber? if not unique_data: # Don't bother spawning it. return FloatingNumber.world_damage( origin=number_origin, # Since `info.damage` is a float, convert it to an integer before # converting it to a string to get rid of the decimal part. number=str(int(info.damage)), color=WHITE, unique_data=unique_data ) # Or from a player? else: try: # Try to get the Player instance of the attacker. player_a = player_instances[index_a] except ValueError: # Damage was caused indirectly (grenade, projectile). try: # Try to get a Player instance again, but this time using the # the owner inthandle of the entity that caused the damage. player_a = player_instances.from_inthandle( Entity(info.inflictor).owner_handle) except (ValueError, OverflowError): # ValueError: not a player. # OverflowError: invalid owner inthandle (-1). return # Is the attacker a bot? if player_a.is_bot(): return # Self inflicted damage? if player_v is player_a: return number_origin = player_v.get_number_origin() velocity = None # Did the bullet go through another entity before hitting the player? if info.penetrated and wall_bangs.get_int(): # Let's check if that entity is the world. trace = GameTrace() engine_trace.clip_ray_to_entity( # Create a Ray() from the attacker's eyes to the hit position. Ray(player_a.eye_location, info.position), ContentMasks.ALL, Entity(WORLD_ENTITY_INDEX), trace ) # Is this an actual wall-bang (bullet went through world)? if trace.did_hit(): # Calculate the directional vector from the wall to the player. from_wall = trace.start_position - trace.end_position # Calculate the offset for the FloatingNumber's new origin. origin_offset = 10 + from_wall.length * 0.01 # Normalize it. # Vector(368.52, 40.71, -7.77) -> Vector(0.99, 0.10, -0.02) from_wall.normalize() # Change the origin of the FloatingNumber so it spawns in front # of the wall where the wall-bang took place. number_origin = trace.end_position + origin_offset * from_wall right, up = Vector(), Vector() from_wall.get_vector_vectors(right, up) velocity = from_wall * 25 + ( right * 35 * player_a.next_direction) # If the bullet went through something else (another player) # before hitting the wall, adjust how high the FloatingNumber # gets pushed. velocity.z = 75 * info.penetrated distance = number_origin.get_distance(player_a.origin) # TODO: Figure out a better way to allow other plugins to change the # color of the FloatingNumber. Or hardcode the colors to unused # DamageTypes (e.g. AIRBOAT = YELLOW, PHYSGUN = BLUE)? color = YELLOW if info.type == DamageTypes.AIRBOAT else WHITE FloatingNumber( origin=number_origin, number=str(int(info.damage)), # Change the color if it's a headshot. color=RED if player_v.last_hitgroup == 1 else color, angle=player_a.view_angle, # Increase the size depending on the distance. size=10 + distance * DISTANCE_MULTIPLIER, recipient=player_a.userid, velocity=velocity )
def create_beam(self): if self.prop is None: raise RuntimeError("Create prop first") end_trace_vec = self.origin + self.normal * MAX_TRACE_LENGTH trace = GameTrace() engine_trace.trace_ray( Ray(self.origin, end_trace_vec), ContentMasks.ALL, TraceFilterSimple(ignore=(self.prop.index, )), trace ) if not trace.did_hit(): return if self.owner.team == teams_by_name['ct']: beam_color = Color(100, 100, 255) else: beam_color = Color(255, 100, 100) self.beam_target = Entity.create("env_spark") self.beam_target.target_name = "_tripmines_target1_{}".format(self.id) self.beam_target.teleport(self.origin, None, None) self.beam_target.spawn() self.beam = Entity.create("env_beam") self.beam.target_name = "_tripmines_beam_{}".format(self.id) self.beam.spawn_flags = 1 self.beam.teleport(trace.end_position, None, None) self.beam.set_key_value_float('BoltWidth', 1.0) self.beam.set_key_value_int('damage', 0) self.beam.set_key_value_float('HDRColorScale', 1.0) self.beam.set_key_value_int('life', 0) self.beam.set_key_value_string( 'LightningStart', self.beam.target_name) self.beam.set_key_value_string( 'LightningEnd', self.beam_target.target_name) self.beam.set_key_value_int('Radius', 255) self.beam.set_key_value_int('renderamt', 100) self.beam.set_key_value_color('rendercolor', beam_color) self.beam.set_key_value_int('StrikeTime', 1) self.beam.set_key_value_string('texture', "sprites/laserbeam.spr") self.beam.set_key_value_int('TextureScroll', 35) self.beam.set_key_value_int('TouchType', 3) self.beam.model = BEAM_MODEL self.beam.set_property_vector('m_vecEndPos', self.origin) self.beam.spawn() self.beam.call_input('TurnOff') self.beam.call_input('TurnOn') self.activated = True if config_manager['activation_sound'] != "": Sound(config_manager['activation_sound'], index=self.prop.index, attenuation=Attenuation.STATIC).play()
def can_see_location(self, vector): "Checks to see if the turret can see the <Vector> provided." trace = GameTrace() engine_trace.trace_ray(self.get_ray(vector), self.mask, self.trace_filter, trace) return not trace.did_hit()