def _dissolve_ragdoll(inthandle, current_type): """Dissolve/remove the player's ragdoll.""" try: entity = Entity(index_from_inthandle(inthandle)) except (OverflowError, ValueError): return # Should the ragdoll just be removed? if current_type == NUM_DISSOLVE_TYPES + 2: entity.remove() return # Set the target name for the player's ragdoll entity.target_name = f'ragdoll_{inthandle}' # Get the dissolver entity dissolver_entity = Entity.find_or_create('env_entity_dissolver') # Should a random dissolve type be chosen? if current_type == NUM_DISSOLVE_TYPES + 1: current_type = randrange(NUM_DISSOLVE_TYPES) # Set the magnitude dissolver_entity.magnitude = dissolver_magnitude.get_int() # Set the dissolve type dissolver_entity.dissolve_type = current_type # Dissolve the ragdoll dissolver_entity.dissolve(f'ragdoll_{inthandle}')
def dissolve_ragdoll(userid, current_type): """Dissolve/remove the player's ragdoll.""" # Get the ragdoll entity try: inthandle = Player.from_userid(userid).ragdoll except ValueError: return if inthandle == INVALID_ENTITY_INTHANDLE: return entity = Entity(index_from_inthandle(inthandle)) # Should the ragdoll just be removed? if current_type == _num_dissolve_types + 2: entity.remove() return # Set the target name for the player's ragdoll entity.target_name = 'ragdoll_{userid}'.format(userid=userid) # Get the dissolver entity dissolver_entity = Entity.find_or_create('env_entity_dissolver') # Should a random dissolve type be chosen? if current_type == _num_dissolve_types + 1: current_type = randrange(_num_dissolve_types) # Set the magnitude dissolver_entity.magnitude = magnitude.get_int() # Set the dissolve type dissolver_entity.dissolve_type = current_type # Dissolve the ragdoll dissolver_entity.dissolve('ragdoll_{userid}'.format(userid=userid))
def _pre_on_take_damage(args): info = make_object(TakeDamageInfo, args[1]) entity = Entity(info.attacker) if info.attacker else None if entity is not None and entity.is_player(): attacker = wcgo.player.Player(entity.index) else: attacker = None victim = wcgo.player.Player(index_from_pointer(args[0])) eargs = { 'attacker': attacker, 'victim': victim, 'info': info, } # Adds the weapon argument dependent on scenario if attacker is not None and attacker.active_weapon != -1: eargs['weapon'] = Weapon(index_from_inthandle(attacker.active_weapon)) else: eargs['weapon'] = None if attacker is None or attacker.userid == victim.userid: victim.hero.execute_skills('player_pre_self_injury', player=victim, **eargs) return if not (attacker.steamid == 'BOT' and attacker.hero is None): attacker.hero.execute_skills('player_pre_attack', player=attacker, **eargs) if not (victim.steamid == 'BOT' and victim.hero is None): victim.hero.execute_skills('player_pre_victim', player=victim, **eargs)
def _player_death(game_event): # Dead Strip remove_idle_weapons(status=GunGameMatchStatus.WARMUP) # Dissolver victim = game_event['userid'] try: inthandle = Player.from_userid(victim).ragdoll except ValueError: return if inthandle == INVALID_ENTITY_INTHANDLE: return entity = Entity(index_from_inthandle(inthandle)) entity.target_name = f'ragdoll_{victim}' dissolver_entity = Entity.find_or_create('env_entity_dissolver') dissolver_entity.magnitude = 2 dissolver_entity.dissolve_type = 0 dissolver_entity.dissolve(f'ragdoll_{victim}') # DeathMatch Delay( delay=2, callback=_respawn_player, args=(victim,), cancel_on_level_end=True, )
def from_inthandle(cls, inthandle): """Create an entity instance from an inthandle. :param int inthandle: The inthandle. :rtype: Entity """ return cls(index_from_inthandle(inthandle))
def current_owner(self): """Return a Entity instance of the weapon's owner.""" # Does no player currently own the weapon? if self.owner == -1: return None # Return a Entity instance of the owner return Entity(index_from_inthandle(self.owner))
def from_inthandle(self, inthandle): """Get an entity instance from an inthandle. :param int inthandle: The inthandle. :rtype: Entity """ return self[index_from_inthandle(inthandle)]
def get_weapon_color(self): """Return a tuple value for the player's active weapon's color.""" try: index = index_from_inthandle(self.active_weapon) except (ValueError, OverflowError): raise ValueError( 'No active weapon found for player "{0}"'.format(self.userid)) return Entity(index).color
def set_weapon_color(self, color): """Set the player's active weapon's color.""" try: index = index_from_inthandle(self.active_weapon) except (ValueError, OverflowError): raise ValueError( 'No active weapon found for player "{0}"'.format(self.userid)) Entity(index).color = color
def get_weapon_color(self): """Return a tuple value for the player's active weapon's color.""" try: index = index_from_inthandle(self.active_weapon) except (ValueError, OverflowError): raise ValueError('No active weapon found for player "{0}"'.format( self.userid)) return Entity(index).color
def set_weapon_color(self, color): """Set the player's active weapon's color.""" try: index = index_from_inthandle(self.active_weapon) except (ValueError, OverflowError): raise ValueError('No active weapon found for player "{0}"'.format( self.userid)) Entity(index).color = color
def from_inthandle(cls, inthandle, caching=None): """Create an entity instance from an inthandle. :param int inthandle: The inthandle. :param bool caching: Whether to lookup the cache for an existing instance or not. :rtype: Entity """ return cls(index_from_inthandle(inthandle), caching=caching)
def owner(self): """Return the entity's owner. :return: None if the entity has no owner. :rtype: Entity """ try: return Entity(index_from_inthandle(self.owner_handle)) except (ValueError, OverflowError): return None
def weapon_indexes( self, classname=None, is_filters=None, not_filters=None): """Iterate over the player's weapon indexes for the given arguments. :return: A generator of indexes. :rtype: generator """ # Is the weapon array supported for the current game? if _weapon_prop_length is None: return # Loop through the length of the weapon array for offset in range(_weapon_prop_length): # Get the player's current weapon at this offset handle = self.get_property_int( '{base}{offset:03d}'.format( base=weapon_manager.myweapons, offset=offset, ) ) # Try to get the index of the handle try: index = index_from_inthandle(handle) except (ValueError, OverflowError): continue # Get the weapon's classname weapon_class = edict_from_index(index).classname # Was a classname given and the current # weapon is not of that classname? if classname is not None and weapon_class != classname: # Do not yield this index continue # Import WeaponClassIter to use its functionality from filters.weapons import WeaponClassIter # Was a weapon type given and the # current weapon is not of that type? if not (is_filters is None and not_filters is None): if weapon_class not in map( lambda value: value.name, WeaponClassIter(is_filters, not_filters)): # Do not yield this index continue # Yield the index yield index
def weapon_indexes(self, classname=None, is_filters=None, not_filters=None): """Iterate over the player's weapon indexes for the given arguments. :return: A generator of indexes. :rtype: generator """ # Is the weapon array supported for the current game? if _weapon_prop_length is None: return # Loop through the length of the weapon array for offset in range(_weapon_prop_length): # Get the player's current weapon at this offset handle = self.get_property_int('{base}{offset:03d}'.format( base=weapon_manager.myweapons, offset=offset, )) # Try to get the index of the handle try: index = index_from_inthandle(handle) except (ValueError, OverflowError): continue # Get the weapon's classname weapon_class = edict_from_index(index).classname # Was a classname given and the current # weapon is not of that classname? if classname is not None and weapon_class != classname: # Do not yield this index continue # Import WeaponClassIter to use its functionality from filters.weapons import WeaponClassIter # Was a weapon type given and the # current weapon is not of that type? if not (is_filters is None and not_filters is None): if weapon_class not in map( lambda value: value.name, WeaponClassIter(is_filters, not_filters)): # Do not yield this index continue # Yield the index yield index
def active_weapon(self): """Return the player's active weapon. :return: None if the player does not have an active weapon. :rtype: Weapon """ try: index = index_from_inthandle(self.active_weapon_handle) except (ValueError, OverflowError): return None return Weapon(index)
def get_active_weapon(self): """Return the player's active weapon. :return: None if the player does not have an active weapon. :rtype: Weapon """ try: index = index_from_inthandle(self.active_weapon_handle) except (ValueError, OverflowError): return None return Weapon(index)
def weapon_indexes( self, classname=None, is_filters=None, not_filters=None): """Iterate over all currently held weapons by thier index.""" # Is the weapon array supported for the current game? if _weapon_prop_length is None: return # Loop through the length of the weapon array for offset in range(_weapon_prop_length): # Get the player's current weapon at this offset handle = self.get_property_int( weapon_manager.myweapons + '%03i' % offset) # Get the weapon's index index = index_from_inthandle(handle, raise_exception=False) # Is this a valid index? if not index: # Move onto the next offset continue # Get the weapon's edict edict = Entity(index) # Get the weapon's classname weapon_class = edict.get_class_name() # Was a classname given and the current # weapon is not of that classname? if classname is not None and weapon_class != classname: # Do not yield this index continue # Import WeaponClassIter to use its functionality from filters.weapons import WeaponClassIter # Was a weapon type given and the # current weapon is not of that type? if not (is_filters is None and not_filters is None): if weapon_class not in list(WeaponClassIter( is_filters, not_filters, 'classname')): # Do not yield this index continue # Yield the index yield index
def get_parent(self): """Return the entity's parent. :rtype: Entity """ # Get the parent handle... parent_inthandle = self.parent_inthandle # Does the entity have no parent? if parent_inthandle == -1: return None # Return the parent of the entity... return Entity(index_from_inthandle(parent_inthandle))
def weapon_indexes(self, classname=None, is_filters=[], not_filters=[]): ''' Iterates over all currently held weapons, and yields their indexes ''' # Loop through the length of m_hMyWeapons for offset in range(64): # Get the player's current weapon at this offset handle = self.GetPropInt(WeaponManager.myweapons + '%03i' % offset) # Is this an invalid handle? if handle == -1: # Move onto the next offset continue # Get the weapon's index index = index_from_inthandle(handle) # Is this a valid index? if index is None: # Move onto the next offset continue # Get the weapon's edict edict = CEdict(index) # Get the weapon's classname weapon_class = edict.get_class_name() # Was a classname given and the current # weapon is not of that classname? if not classname is None and weapon_class != classname: # Do not yield this index continue # Was a weapon type given and the # current weapon is not of that type? if ((is_filters or not_filters) and not weapon_class in list( WeaponClassIter(is_filters, not_filters, 'classname'))): # Do not yield this index continue # Yield the index yield index
def get_weapon_color(self): """Return a tuple value for the player's active weapon's color.""" # Get the handle of the player's active weapon handle = self.active_weapon # Get the weapon's BaseHandle instance index = index_from_inthandle(handle) # Was no index found? if index is None: # Raise an error raise ValueError( 'No active weapon found for player "{0}"'.format(self.userid)) # Return the entity's color return Entity(index).color
def set_weapon_color(self, red, green, blue, alpha=None): """Set the player's active weapon's color.""" # Get the handle of the player's active weapon handle = self.active_weapon # Get the weapon's BaseHandle instance index = index_from_inthandle(handle) # Was no index found? if index is None: # Raise an error raise ValueError( 'No active weapon found for player "{0}"'.format(self.userid)) # Set the entity's color Entity(index).color = (red, green, blue, alpha)
def weapon_indexes(self, classname=None, is_filters=None, not_filters=None): """Iterate over all currently held weapons by thier index.""" # Is the weapon array supported for the current game? if _weapon_prop_length is None: return # Loop through the length of the weapon array for offset in range(_weapon_prop_length): # Get the player's current weapon at this offset handle = self.get_property_int(weapon_manager.myweapons + '%03i' % offset) try: index = index_from_inthandle(handle) except (ValueError, OverflowError): continue # Get the weapon's classname weapon_class = edict_from_index(index).classname # Was a classname given and the current # weapon is not of that classname? if classname is not None and weapon_class != classname: # Do not yield this index continue # Import WeaponClassIter to use its functionality from filters.weapons import WeaponClassIter # Was a weapon type given and the # current weapon is not of that type? if not (is_filters is None and not_filters is None): if weapon_class not in map( lambda value: value.name, WeaponClassIter(is_filters, not_filters)): # Do not yield this index continue # Yield the index yield index
def _remove_model(userid): for inthandle in _game_models: if userid == _game_models[inthandle]: try: index = index_from_inthandle(inthandle) except ValueError: pass else: entity = Entity(index) entity.clear_parent() entity.call_input('FireUser1', '1') finally: del _game_models[inthandle] return inthandle return None
def listener_on_tick(): for sprinting_player in player_manager.values(): if sprinting_player.player.ground_entity == -1: sprinting_player.ensure_speed(AIRBORNE_PLAYER_SPEED) else: if sprinting_player.sprinting: sprinting_player.ensure_speed(SPRINTING_PLAYER_SPEED) else: sprinting_player.ensure_speed(DEFAULT_PLAYER_SPEED) if sprinting_player.sprinting: inthandle = sprinting_player.player.active_weapon if inthandle == INVALID_ENTITY_INTHANDLE: continue entity = Entity(index_from_inthandle(inthandle)) entity.next_attack = global_vars.current_time + 1 entity.next_secondary_fire_attack = global_vars.current_time + 1
def weapon_indexes( self, classname=None, is_filters=None, not_filters=None): """Iterate over all currently held weapons by thier index.""" # Is the weapon array supported for the current game? if _weapon_prop_length is None: return # Loop through the length of the weapon array for offset in range(_weapon_prop_length): # Get the player's current weapon at this offset handle = self.get_property_int( weapon_manager.myweapons + '%03i' % offset) try: index = index_from_inthandle(handle) except (ValueError, OverflowError): continue # Get the weapon's classname weapon_class = edict_from_index(index).classname # Was a classname given and the current # weapon is not of that classname? if classname is not None and weapon_class != classname: # Do not yield this index continue # Import WeaponClassIter to use its functionality from filters.weapons import WeaponClassIter # Was a weapon type given and the # current weapon is not of that type? if not (is_filters is None and not_filters is None): if weapon_class not in map( lambda value: value.name, WeaponClassIter(is_filters, not_filters)): # Do not yield this index continue # Yield the index yield index
def take_damage( self, damage, damage_type=DamageTypes.GENERIC, attacker_index=None, weapon_index=None, hitgroup=HitGroup.GENERIC, skip_hooks=False, **kwargs): """Method used to hurt the entity with the given arguments.""" # Import Entity classes # Doing this in the global scope causes cross import errors from weapons.entity import Weapon # Is the game supported? if not hasattr(self, 'on_take_damage'): # Raise an error if not supported raise NotImplementedError( '"take_damage" is not implemented for {0}'.format(GAME_NAME)) # Store values for later use attacker = None weapon = None # Was an attacker given? if attacker_index is not None: # Try to get the Entity instance of the attacker with suppress(ValueError): attacker = Entity(attacker_index) # Was a weapon given? if weapon_index is not None: # Try to get the Weapon instance of the weapon with suppress(ValueError): weapon = Weapon(weapon_index) # Is there a weapon but no attacker? if attacker is None and weapon is not None: # Try to get the attacker based off of the weapon's owner with suppress(ValueError, OverflowError): attacker_index = index_from_inthandle(weapon.current_owner) attacker = Entity(attacker_index) # Is there an attacker but no weapon? if attacker is not None and weapon is None: # Try to use the attacker's active weapon with suppress(AttributeError, ValueError, OverflowError): weapon = Weapon(index_from_inthandle(attacker.active_weapon)) # Try to set the hitgroup with suppress(AttributeError): self.hitgroup = hitgroup # Get a TakeDamageInfo instance take_damage_info = TakeDamageInfo() # Is there a valid weapon? if weapon is not None: # Is the weapon a projectile? if weapon.classname in _projectile_weapons: # Set the inflictor to the weapon's index take_damage_info.inflictor = weapon.index # Is the weapon not a projectile and the attacker is valid? elif attacker_index is not None: # Set the inflictor to the attacker's index take_damage_info.inflictor = attacker_index # Set the weapon to the weapon's index take_damage_info.weapon = weapon.index # Is the attacker valid? if attacker_index is not None: # Set the attacker to the attacker's index take_damage_info.attacker = attacker_index # Set the damage amount take_damage_info.damage = damage # Set the damage type value take_damage_info.type = damage_type # Loop through the given keywords for item in kwargs: # Set the offset's value setattr(take_damage_info, item, kwargs[item]) if skip_hooks: self.on_take_damage.skip_hooks(take_damage_info) else: self.on_take_damage(take_damage_info)
def take_damage(self, damage, damage_type=DamageTypes.GENERIC, attacker_index=None, weapon_index=None, hitgroup=HitGroup.GENERIC, skip_hooks=False, **kwargs): """Deal damage to the entity. :param int damage: Amount of damage to deal. :param DamageTypes damage_type: Type of the dealed damage. :param int attacker_index: If not None, the index will be used as the attacker. :param int weapon_index: If not None, the index will be used as the weapon. This method also tries to retrieve the attacker from the weapon, if ``attacker_index`` wasn't set. :param HitGroup hitgroup: The hitgroup where the damage should be applied. :param bool skip_hooks: If True, the damage will be dealed directly by skipping any registered hooks. """ # Import Entity classes # Doing this in the global scope causes cross import errors from weapons.entity import Weapon # Is the game supported? if not hasattr(self, 'on_take_damage'): # Raise an error if not supported raise NotImplementedError( '"take_damage" is not implemented for {0}'.format(GAME_NAME)) # Store values for later use attacker = None weapon = None # Was an attacker given? if attacker_index is not None: # Try to get the Entity instance of the attacker with suppress(ValueError): attacker = Entity(attacker_index) # Was a weapon given? if weapon_index is not None: # Try to get the Weapon instance of the weapon with suppress(ValueError): weapon = Weapon(weapon_index) # Is there a weapon but no attacker? if attacker is None and weapon is not None: # Try to get the attacker based off of the weapon's owner with suppress(ValueError, OverflowError): attacker_index = index_from_inthandle(weapon.owner_handle) attacker = Entity(attacker_index) # Is there an attacker but no weapon? if attacker is not None and weapon is None: # Try to use the attacker's active weapon with suppress(AttributeError): weapon = attacker.active_weapon # Try to set the hitgroup with suppress(AttributeError): self.hitgroup = hitgroup # Get a TakeDamageInfo instance take_damage_info = TakeDamageInfo() # Is there a valid weapon? if weapon is not None: # Is the weapon a projectile? if weapon.classname in _projectile_weapons: # Set the inflictor to the weapon's index take_damage_info.inflictor = weapon.index # Is the weapon not a projectile and the attacker is valid? elif attacker_index is not None: # Set the inflictor to the attacker's index take_damage_info.inflictor = attacker_index # Set the weapon to the weapon's index take_damage_info.weapon = weapon.index # Is the attacker valid? if attacker_index is not None: # Set the attacker to the attacker's index take_damage_info.attacker = attacker_index # Set the damage amount take_damage_info.damage = damage # Set the damage type value take_damage_info.type = damage_type # Loop through the given keywords for item in kwargs: # Set the offset's value setattr(take_damage_info, item, kwargs[item]) if skip_hooks: self.on_take_damage.skip_hooks(take_damage_info) else: self.on_take_damage(take_damage_info)
def take_damage( self, damage, damage_type=DamageTypes.GENERIC, attacker_index=None, weapon_index=None, hitgroup=HitGroup.GENERIC, skip_hooks=False, **kwargs): """Deal damage to the entity. :param int damage: Amount of damage to deal. :param DamageTypes damage_type: Type of the dealed damage. :param int attacker_index: If not None, the index will be used as the attacker. :param int weapon_index: If not None, the index will be used as the weapon. This method also tries to retrieve the attacker from the weapon, if ``attacker_index`` wasn't set. :param HitGroup hitgroup: The hitgroup where the damage should be applied. :param bool skip_hooks: If True, the damage will be dealed directly by skipping any registered hooks. """ # Import Entity classes # Doing this in the global scope causes cross import errors from weapons.entity import Weapon # Is the game supported? if not hasattr(self, 'on_take_damage'): # Raise an error if not supported raise NotImplementedError( '"take_damage" is not implemented for {0}'.format(GAME_NAME)) # Store values for later use attacker = None weapon = None # Was an attacker given? if attacker_index is not None: # Try to get the Entity instance of the attacker with suppress(ValueError): attacker = Entity(attacker_index) # Was a weapon given? if weapon_index is not None: # Try to get the Weapon instance of the weapon with suppress(ValueError): weapon = Weapon(weapon_index) # Is there a weapon but no attacker? if attacker is None and weapon is not None: # Try to get the attacker based off of the weapon's owner with suppress(ValueError, OverflowError): attacker_index = index_from_inthandle(weapon.owner_handle) attacker = Entity(attacker_index) # Is there an attacker but no weapon? if attacker is not None and weapon is None: # Try to use the attacker's active weapon with suppress(AttributeError): weapon = attacker.active_weapon # Try to set the hitgroup with suppress(AttributeError): self.hitgroup = hitgroup # Get a TakeDamageInfo instance take_damage_info = TakeDamageInfo() # Is there a valid weapon? if weapon is not None: # Is the weapon a projectile? if weapon.classname in _projectile_weapons: # Set the inflictor to the weapon's index take_damage_info.inflictor = weapon.index # Is the weapon not a projectile and the attacker is valid? elif attacker_index is not None: # Set the inflictor to the attacker's index take_damage_info.inflictor = attacker_index # Set the weapon to the weapon's index take_damage_info.weapon = weapon.index # Is the attacker valid? if attacker_index is not None: # Set the attacker to the attacker's index take_damage_info.attacker = attacker_index # Set the damage amount take_damage_info.damage = damage # Set the damage type value take_damage_info.type = damage_type # Loop through the given keywords for item in kwargs: # Set the offset's value setattr(take_damage_info, item, kwargs[item]) if skip_hooks: self.on_take_damage.skip_hooks(take_damage_info) else: self.on_take_damage(take_damage_info)
def damage( self, victim_index, damage=0, damage_type=0, weapon_index=None, hitgroup=0, **kwargs): '''Method used to hurt another entity with the given arguments''' # Import BaseEntity classes # Doing this in the global scope causes cross import errors from entities.entity import BaseEntity from players.entity import PlayerEntity # Is the game supported? if not 'TakeDamage' in SignatureDictionary: # Raise an error if not supported raise NotImplementedError( 'damage is not implemented for {0}'.format(GAME_NAME)) # Was no weapon index given? if weapon_index is None and hasattr(self, 'active_weapon'): # Get the player's active weapon weapon_index = index_from_inthandle(self.active_weapon) # Get the weapon's BaseEntity instance weapon = BaseEntity(weapon_index) # Get the victim's BaseEntity instance. victim = BaseEntity(victim_index) # Is the victim a player? if victim.classname == 'player': # Get the victim's PlayerEntity instance instead victim = PlayerEntity(victim_index) # Is hitgroup a valid attribute? if hasattr(victim, 'hitgroup'): # Set the victim's hitgroup victim.hitgroup = hitgroup # Get a memory address for CTakeDamageInfo take_damage_info = Binutils.AllocateMemory(96) # Is the weapon a projectile? if weapon.classname in _projectile_weapons: # Set the hInflictor to the weapon's handle Binutils.SetLocInt( take_damage_info + DamageOffsets.hInflictor, weapon.handle.ToInt()) # Is the weapon not a projectile? else: # Set the hInflictor to the entity's handle Binutils.SetLocInt( take_damage_info + DamageOffsets.hInflictor, self.handle.ToInt()) # Set the hAttacker to the entity's handle Binutils.SetLocInt( take_damage_info + DamageOffsets.hAttacker, self.handle.ToInt()) # Set the hWeapon to the weapon's handle Binutils.SetLocInt( take_damage_info + DamageOffsets.hWeapon, weapon.handle.ToInt()) # Set the flDamage amount Binutils.SetLocFloat( take_damage_info + DamageOffsets.flDamage, float(damage)) # Set the bitsDamageType value Binutils.SetLocInt( take_damage_info + DamageOffsets.bitsDamageType, damage_type) # Loop through the given keywords for item in kwargs: # Is the keyword supported? if item in DamageOffsets: # Set the offset's value getattr( Binutils, 'SetLoc{0}'.format(DamageOffsets[item]['type']))( take_damage_info + DamageOffsets[item]['offset'], kwargs[item]) # Call the function with the victim's pointer and the CTakeDamageInfo SignatureDictionary['TakeDamage'].call_function( victim.pointer, take_damage_info) # Deallocate the memory used for CTakeDamageInfo Binutils.DeallocatePointer(take_damage_info)