예제 #1
0
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}')
예제 #2
0
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))
예제 #3
0
파일: wcgo.py 프로젝트: Ayuto/Warcraft-GO
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)
예제 #4
0
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,
    )
예제 #5
0
    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))
예제 #6
0
    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))
예제 #7
0
    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))
예제 #8
0
    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))
예제 #9
0
 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 from_inthandle(self, inthandle):
     """Get an entity instance from an inthandle.
     
     :param int inthandle:
         The inthandle.
     :rtype: Entity
     """
     return self[index_from_inthandle(inthandle)]
예제 #11
0
    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
예제 #12
0
    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
예제 #13
0
    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
예제 #14
0
    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
예제 #15
0
    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)
예제 #16
0
    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
예제 #17
0
    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
예제 #18
0
    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
예제 #19
0
    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
예제 #20
0
    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)
예제 #21
0
    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)
예제 #22
0
    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
예제 #23
0
    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))
예제 #24
0
    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))
예제 #25
0
    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
예제 #26
0
    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
예제 #27
0
    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)
예제 #28
0
    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
예제 #29
0
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
예제 #30
0
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
예제 #31
0
    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
예제 #32
0
    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)
예제 #33
0
    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)
예제 #34
0
    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)
예제 #35
0
    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)
예제 #36
0
    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)