Page 1 of 2

Get Attackerweapon from TakeDamageInfo

Posted: Sun May 10, 2015 4:54 pm
by RoOF
Yo Guys,

One Question:

How can i get the attackweapon from TakeDamageInfo ?


tried it this way:


Syntax: Select all

@PreHook(OnTakeDamage)
def pre_on_take_damage(args):
attack = make_object(TakeDamageInfo, args[1]) # args[0] = victim | args[1] = attacker
print (attack.weapon)



It prints me allways "-1"

Any Ideas ?

Posted: Sun May 10, 2015 5:43 pm
by L'In20Cible
The "weapon" attribute is not filled by the engine. You need to get the attacker's active weapon.

Syntax: Select all

from players.entity import PlayerEntity
from memory.hooks import PreHook
from memory import make_object
from entities import TakeDamageInfo
from entities.helpers import index_from_inthandle
from weapons.entity import WeaponEntity

@PreHook(<OnTakeDamage's Function>)
def pre_on_take_damage(args):
info = make_object(TakeDamageInfo, args[1])

weapon = None
if info.attacker != 0:
attacker = PlayerEntity(info.attacker)
weapon = WeaponEntity(index_from_inthandle(attacker.active_weapon))

if weapon is not None:
print(attacker.name, 'attacked with a', weapon.get_class_name())

Posted: Sun May 10, 2015 7:15 pm
by satoon101
Don't forget that if a projectile is used, the inflictor will be the weapon and not the attacker. In this case, you wouldn't want to get the active weapon.

Posted: Sun May 10, 2015 11:46 pm
by L'In20Cible
Good point!

Posted: Sun May 10, 2015 11:56 pm
by satoon101
I guess it would have helped to provide an example, sorry:

Syntax: Select all

@PreHook(<OnTakeDamage>)
def pre_take_damage(args):
info = make_object(TakeDamageInfo, args[1])

# Is this world damage?
if info.attacker == 0:
return

victim = PlayerEntity(index_from_pointer(args[0]))
attacker = PlayerEntity(info.attacker)

# Is this self damage?
if victim.index == attacker.index:
return

# Was a normal weapon (non-projectile) used?
if info.attacker == info.inflictor:
weapon = WeaponEntity(index_from_inthandle(attacker.active_weapon))

# Was a projectile used?
else:
weapon = WeaponEntity(info.inflictor)

print('{0} was attacked by {1} with a {2}'.format(victim.name, attacker.name, weapon.classname))

Posted: Wed May 27, 2015 3:41 am
by arawra
So neither of these examples have worked for me. I'm guessing its because of a new release/syntax. Would it be possible to get an updated version of these scripts?

For example, @PreHook(<entity>) always errors because of the arrows in the syntax.

Posted: Wed May 27, 2015 4:05 am
by satoon101
You have to replace <OnTakeDamage> with the actual function of OnTakeDamage. In RoOF's example, he didn't provide exactly how he got the function, so both L'In20Cible and I used place holders. Anytime you see <Something> in code, you will need to replace that with what it is referencing. For the current example, you can do it a couple different ways now:

Syntax: Select all

from engines.server import engine_server
from entities import TakeDamageInfo
from entities.helpers import index_from_pointer
from filters.players import PlayerIter
from memory import make_object
from memory.hooks import PreHook
from players.bots import bot_manager
from players.entity import PlayerEntity
from weapons.entity import WeaponEntity

for _player in PlayerIter(return_types='player'):
on_take_damage = _player.on_take_damage
break
else:
_player = PlayerEntity(
index_from_edict(bot_manager.create_bot('test_bot')))
on_take_damage = _player.on_take_damage
engine_server.server_command('kickid {0};'.format(_player.userid))


@PreHook(on_take_damage)
def pre_on_take_damage(args):
...


Also, we haven't come to a full decision of where the new EntityPreHook and EntityPostHook classes will be housed, but for the moment they are in memory.hooks:

Syntax: Select all

from entities import TakeDamageInfo
from entities.helpers import index_from_pointer
from memory import make_object
from memory.hooks import EntityPreHook
from players.entity import PlayerEntity
from weapons.entity import WeaponEntity


@EntityPreHook(['cs_bot', 'player'], 'on_take_damage')
def pre_on_take_damage(args):
...

Posted: Wed May 27, 2015 4:29 am
by arawra
EntityPreHook can't be found from memory.hooks.
E: I just checked the repo, and apparently my version differs. Updating again...
EE: Looks like I need to build from source?

This crashes the server:

Syntax: Select all

from engines.server import engine_server
from entities import TakeDamageInfo
from entities.helpers import index_from_pointer
from entities.helpers import index_from_edict
from entities.helpers import index_from_inthandle
from filters.players import PlayerIter
from memory import make_object
from memory.hooks import PreHook
from players.bots import bot_manager
from players.entity import PlayerEntity
from weapons.entity import WeaponEntity

for _player in PlayerIter(return_types='player'):
on_take_damage = _player.on_take_damage
break
else:
_player = PlayerEntity(
index_from_edict(bot_manager.create_bot('test_bot')))
on_take_damage = _player.on_take_damage
engine_server.server_command('kickid {0};'.format(_player.userid))

@PreHook(on_take_damage)
def pre_on_take_damage(args):
info = make_object(TakeDamageInfo, args[1])

# Is this world damage?
if info.attacker == 0:
return

victim = PlayerEntity(index_from_pointer(args[0]))
attacker = PlayerEntity(info.attacker)

# Is this self damage?
if victim.index == attacker.index:
return

# Was a normal weapon (non-projectile) used?
if info.attacker == info.inflictor:
weapon = WeaponEntity(index_from_inthandle(attacker.active_weapon))

# Was a projectile used?
else:
weapon = WeaponEntity(info.inflictor)

print('{0} was attacked by {1} with a {2}'.format(victim.name, attacker.name, weapon.classname))

Posted: Wed May 27, 2015 4:39 am
by satoon101
Do note that you cannot load that test script in your autoexec.cfg as you cannot add bots when no map is loaded.

Posted: Wed May 27, 2015 4:57 am
by arawra
Whats the trick to getting this sort of script to load automatically after map start?

Posted: Wed May 27, 2015 5:08 am
by satoon101
That issue is one of the many reasons we designed the EntityPreHook/EntityPostHook classes. With those classes, you can load the script during map change or server startup and not have any issues. For now, you can just delay the loading in your cfg file by using sp delay:

Code: Select all

sp delay 0 sp load test

Posted: Wed May 27, 2015 8:13 am
by arawra
This crashes my server when I try to join.

Syntax: Select all

from entities import TakeDamageInfo
from entities.helpers import index_from_pointer
from memory import make_object
from memory.hooks import EntityPreHook
from players.entity import PlayerEntity
from weapons.entity import WeaponEntity


@EntityPreHook(['cs_bot', 'player'], 'on_take_damage')
def pre_on_take_damage(args):
info = make_object(TakeDamageInfo, args[1])


E: This seems to only happen for the very same reason in the other script. It will crash only if the script is loaded AFTER player joins only if there were no bots or players already present.

Posted: Wed May 27, 2015 10:49 am
by L'In20Cible
This works fine for me in both cases. Please, always tell the game you are testing on as you know we will ask for it.

Posted: Wed May 27, 2015 11:00 am
by arawra
CS:GO with the latest source for SP

Image

Posted: Wed May 27, 2015 11:11 am
by arawra
Just to be certain, I also tried with the latest release.

Code: Select all

[SP] Loading plugin 'damagetest'...

[SP] Caught an Exception:
Traceback (most recent call last):
  File '..\addons\source-python\packages\source-python\plugins\manager.py', line 72, in __missing__
    instance = self.instance(plugin_name, self.base_import)
  File '..\addons\source-python\packages\source-python\plugins\instance.py', line 82, in __init__
    self._plugin = import_module(import_name)
  File '..\addons\source-python\plugins\damagetest\damagetest.py', line 4, in <module>
    from memory.hooks import EntityPreHook

ImportError: cannot import name 'EntityPreHook'

Posted: Wed May 27, 2015 11:29 am
by L'In20Cible
I just tested on CS:GO and CS:S and they both worked fine for me. Not sure what to tell you, actually. What other plugins are you running? Try disable everything except last compiled source and the litle snippet you posted above.

Posted: Wed May 27, 2015 11:41 am
by arawra
Thats literally all I had - latest compiled SP with that little snippet. You can see my autoexec in the back there.

Posted: Wed May 27, 2015 2:21 pm
by satoon101
Those 2 classes are not included in the latest release. Give us time to sort out some issues and we will post another release. If you know how to compile on your own, feel free to get the latest version from the repo and compile the binaries. Since you are on Windows, maybe this wiki page can help you if you don't know how to compile:
http://wiki.sourcepython.com/pages/Tutorials:Building_on_Windows

Posted: Wed May 27, 2015 2:38 pm
by arawra
arawra wrote:I had - latest compiled SP


:>) Compiled from last night's source.

Posted: Wed May 27, 2015 3:11 pm
by Ayuto
If you are getting the ImportError, you probably didn't update your Python files.