TF2 - Getting weapon names from event byte

Please post any questions about developing your plugin here. Please use the search function before posting!
User avatar
Zeus
Member
Posts: 52
Joined: Sat Mar 24, 2018 5:25 pm
Location: Chicago
Contact:

TF2 - Getting weapon names from event byte

Postby Zeus » Sun Sep 02, 2018 4:35 pm

Hello!

Some events return a 'byte' that represents the weapon used by a player. Example: http://wiki.sourcepython.com/developing ... ayer-shoot

I would like to get the string representation of that weapon (i.e. tf_weapon_scattergun). I know this changes with every update (what few of them there are); so I'd like it if I could just ask the srcds process what it actually is since it would know.

Just wondering if anyone has a method of retrieving the weapon name and some properties of those guns such as uber charge percentage?
User avatar
Kami
Global Moderator
Posts: 263
Joined: Wed Aug 15, 2012 1:24 am
Location: Germany

Re: TF2 - Getting weapon names from event byte

Postby Kami » Sun Sep 02, 2018 6:22 pm

Hey,

wouldn't it work to just get the players active weapon on those events? In case of player_shoot the active_weapon would be the one he shoots with and I think every event that includes a weapon refers to the active weapon.

Syntax: Select all

@Event('player_shoot')
def _player_shoot(ev):
player = Player.from_userid(ev['userid'])
weapon = player.active_weapon # active_weapon returns a Weapon class
weapon_name = weapon.class_name #if you need the actual name of the weapon (like tf_weapon_scattergun)


For properties I do not know the properties for tf2 too well but you could always iterate over the properties with source python and see what you can use.


Syntax: Select all

@Event('player_shoot')
def _player_shoot(ev):
player = Player.from_userid(ev['userid'])
weapon = player.active_weapon
for property in weapon.properties:
print(property)


I like to write those properties to a file instead of printing them to the console though.

If you want to write the properties to file you could use this:

Syntax: Select all

@Event('player_shoot')
def _player_shoot(ev):
player = Player.from_userid(ev['userid'])
weapon = player.active_weapon
weapon_file = open(weapon.class_name+"_properties.txt",'w')
for property in weapon.properties:
weapon_file.write(x)
weapon_file.write("\n")
weapon_file.close()
User avatar
Zeus
Member
Posts: 52
Joined: Sat Mar 24, 2018 5:25 pm
Location: Chicago
Contact:

Re: TF2 - Getting weapon names from event byte

Postby Zeus » Sun Sep 02, 2018 9:40 pm

Hmm that is a good thought!

however it wouldn't be entirely accurate to do it that way unfortunately

Some classes like demo can det his stickies with any weapon equipped. Or projectile weapons can kill while the equipped weapon is switched off before it hits. Not to mention sentry guns, bleed, jarate, gas passer.
User avatar
L'In20Cible
Project Leader
Posts: 1533
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: TF2 - Getting weapon names from event byte

Postby L'In20Cible » Mon Sep 03, 2018 2:30 pm

The byte is probably the index of the entity:

Syntax: Select all

weapon = Weapon(ev['weapon'])
User avatar
Zeus
Member
Posts: 52
Joined: Sat Mar 24, 2018 5:25 pm
Location: Chicago
Contact:

Re: TF2 - Getting weapon names from event byte

Postby Zeus » Mon Sep 03, 2018 6:43 pm

L'In20Cible wrote:The byte is probably the index of the entity:

Syntax: Select all

weapon = Weapon(ev['weapon'])


Ah yeah that was a good thought as well; but did not work. It looks like it's refering to this here: https://wiki.alliedmods.net/Team_Fortre ... on_Indexes

It doesnt appear to be an entity index. It also doesnt look like tf2 uses the same 'weapon' objects as other source games.
User avatar
Kami
Global Moderator
Posts: 263
Joined: Wed Aug 15, 2012 1:24 am
Location: Germany

Re: TF2 - Getting weapon names from event byte

Postby Kami » Mon Sep 03, 2018 7:35 pm

Could you show us some code maybe? I tried to use player_shoot but it did not trigger when shooting a weapon.
Are there any other events that return bytes for weapons? I could onylf ind player_shoot
User avatar
Zeus
Member
Posts: 52
Joined: Sat Mar 24, 2018 5:25 pm
Location: Chicago
Contact:

Re: TF2 - Getting weapon names from event byte

Postby Zeus » Tue Sep 04, 2018 12:44 am

Yeah im not sure why player shoot does not trigger. I was gonna ask about that lol. Im assuming there is just some offset not set right?

This is the code im currently testing with



Code: Select all

from entities.entity import Entity
from weapons.entity import Weapon

@Event("player_hurt")
def damage(event):
    args = event.variables.as_dict()
    wepid = args['weaponid']

    wep = Entity(wepid)
    wep = Weapon(wepid)


Both entity and weapon will stack trace saying that it requires an index.

The 'weaponid' does appear to come from this giant file: http://git.optf2.com/schema-tracking/pl ... mfortress2

So it's possible i could just scrape it from there any try to line up the ID's. Just seems like this is something the game engine would certainally konw about
User avatar
L'In20Cible
Project Leader
Posts: 1533
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: TF2 - Getting weapon names from event byte

Postby L'In20Cible » Tue Sep 04, 2018 1:08 am

Seems like this is the enumerated type (untested):

Syntax: Select all

# ============================================================================
# >> IMPORTS
# ============================================================================
# Python
from enum import IntEnum
# Source.Python Imports
from events import Event


# ============================================================================
# >> ENUMERATORS
# ============================================================================
class TF2_WeaponType(IntEnum):
"""Values taken from: https://tinyurl.com/ydbvo62k"""

NONE = 0
BAT = 1
BAT_WOOD = 2
BOTTLE = 3
FIREAXE = 4
CLUB = 5
CROWBAR = 6
KNIFE = 7
FISTS = 8
SHOVEL = 9
WRENCH = 10
BONESAW = 11
SHOTGUN_PRIMARY = 12
SHOTGUN_SOLDIER = 13
SHOTGUN_HWG = 14
SHOTGUN_PYRO = 15
SCATTERGUN = 16
SNIPERRIFLE = 17
MINIGUN = 18
SMG = 19
SYRINGEGUN_MEDIC = 20
TRANQ = 21
ROCKETLAUNCHER = 22
GRENADELAUNCHER = 23
PIPEBOMBLAUNCHER = 24
FLAMETHROWER = 25
GRENADE_NORMAL = 26
GRENADE_CONCUSSION = 27
GRENADE_NAIL = 28
GRENADE_MIRV = 29
GRENADE_MIRV_DEMOMAN = 30
GRENADE_NAPALM = 31
GRENADE_GAS = 32
GRENADE_EMP = 33
GRENADE_CALTROP = 34
GRENADE_PIPEBOMB = 35
GRENADE_SMOKE_BOMB = 36
GRENADE_HEAL = 37
GRENADE_STUNBALL = 38
GRENADE_JAR = 39
GRENADE_JAR_MILK = 40
PISTOL = 41
PISTOL_SCOUT = 42
REVOLVER = 43
NAILGUN = 44
PDA = 45
PDA_ENGINEER_BUILD = 46
PDA_ENGINEER_DESTROY = 47
PDA_SPY = 48
BUILDER = 49
MEDIGUN = 50
GRENADE_MIRVBOMB = 51
FLAMETHROWER_ROCKET = 52
GRENADE_DEMOMAN = 53
SENTRY_BULLET = 54
SENTRY_ROCKET = 55
DISPENSER = 56
INVIS = 57
FLAREGUN = 58
LUNCHBOX = 59
JAR = 60
COMPOUND_BOW = 61
BUFF_ITEM = 62
PUMPKIN_BOMB = 63
SWORD = 64
DIRECTHIT = 65
LIFELINE = 66
LASER_POINTER = 67
DISPENSER_GUN = 68
SENTRY_REVENGE = 69
JAR_MILK = 70
HANDGUN_SCOUT_PRIMARY = 71
BAT_FISH = 72
CROSSBOW = 73
STICKBOMB = 74
HANDGUN_SCOUT_SEC = 75
SODA_POPPER = 76
SNIPERRIFLE_DECAP = 77
RAYGUN = 78
PARTICLE_CANNON = 79
MECHANICAL_ARM = 80
DRG_POMSON = 81
BAT_GIFTWRAP = 82
GRENADE_ORNAMENT = 83
RAYGUN_REVENGE = 84
PEP_BRAWLER_BLASTER = 85
CLEAVER = 86
GRENADE_CLEAVER = 87
STICKY_BALL_LAUNCHER = 88
GRENADE_STICKY_BALL = 89
SHOTGUN_BUILDING_RESCUE = 90
CANNON = 91
THROWABLE = 92
GRENADE_THROWABLE = 93
PDA_SPY_BUILD = 94
GRENADE_WATERBALLOON = 95
HARVESTER_SAW = 96
SPELLBOOK = 97
SPELLBOOK_PROJECTILE = 98
SNIPERRIFLE_CLASSIC = 99
PARACHUTE = 100
GRAPPLINGHOOK = 101
PASSTIME_GUN = 102
CHARGED_SMG = 103
BREAKABLE_SIGN = 104
ROCKETPACK = 105
SLAP = 106
JAR_GAS = 107
GRENADE_JAR_GAS = 108
FLAME_BALL = 109


# ============================================================================
# >> EVENTS
# ============================================================================
@Event('player_hurt')
def on_player_hurt(game_event):
"""Game event fired when a player receives damage."""

# Get the weapon type causing the damage...
weapon_type = TF2_WeaponType(game_event.get_int('weaponid'))


Zeus wrote:Yeah im not sure why player shoot does not trigger. I was gonna ask about that lol. Im assuming there is just some offset not set right?

Even if the events are declared, this is up to the game to fire them. Source.Python only listen for the fired events and call the registered callbacks that matches the name. I'm pretty sure player_shoot is some old event from HL2 that is carried in the SDK and is never used by any later games.
User avatar
Zeus
Member
Posts: 52
Joined: Sat Mar 24, 2018 5:25 pm
Location: Chicago
Contact:

Re: TF2 - Getting weapon names from event byte

Postby Zeus » Tue Sep 04, 2018 3:33 pm

L'In20Cible wrote:Seems like this is the enumerated type (untested):

Syntax: Select all

# ============================================================================
# >> IMPORTS
# ============================================================================
# Python
from enum import IntEnum
# Source.Python Imports
from events import Event


# ============================================================================
# >> ENUMERATORS
# ============================================================================
class TF2_WeaponType(IntEnum):
"""Values taken from: https://tinyurl.com/ydbvo62k"""

NONE = 0
BAT = 1
BAT_WOOD = 2
BOTTLE = 3
FIREAXE = 4
CLUB = 5
CROWBAR = 6
KNIFE = 7
FISTS = 8
SHOVEL = 9
WRENCH = 10
BONESAW = 11
SHOTGUN_PRIMARY = 12
SHOTGUN_SOLDIER = 13
SHOTGUN_HWG = 14
SHOTGUN_PYRO = 15
SCATTERGUN = 16
SNIPERRIFLE = 17
MINIGUN = 18
SMG = 19
SYRINGEGUN_MEDIC = 20
TRANQ = 21
ROCKETLAUNCHER = 22
GRENADELAUNCHER = 23
PIPEBOMBLAUNCHER = 24
FLAMETHROWER = 25
GRENADE_NORMAL = 26
GRENADE_CONCUSSION = 27
GRENADE_NAIL = 28
GRENADE_MIRV = 29
GRENADE_MIRV_DEMOMAN = 30
GRENADE_NAPALM = 31
GRENADE_GAS = 32
GRENADE_EMP = 33
GRENADE_CALTROP = 34
GRENADE_PIPEBOMB = 35
GRENADE_SMOKE_BOMB = 36
GRENADE_HEAL = 37
GRENADE_STUNBALL = 38
GRENADE_JAR = 39
GRENADE_JAR_MILK = 40
PISTOL = 41
PISTOL_SCOUT = 42
REVOLVER = 43
NAILGUN = 44
PDA = 45
PDA_ENGINEER_BUILD = 46
PDA_ENGINEER_DESTROY = 47
PDA_SPY = 48
BUILDER = 49
MEDIGUN = 50
GRENADE_MIRVBOMB = 51
FLAMETHROWER_ROCKET = 52
GRENADE_DEMOMAN = 53
SENTRY_BULLET = 54
SENTRY_ROCKET = 55
DISPENSER = 56
INVIS = 57
FLAREGUN = 58
LUNCHBOX = 59
JAR = 60
COMPOUND_BOW = 61
BUFF_ITEM = 62
PUMPKIN_BOMB = 63
SWORD = 64
DIRECTHIT = 65
LIFELINE = 66
LASER_POINTER = 67
DISPENSER_GUN = 68
SENTRY_REVENGE = 69
JAR_MILK = 70
HANDGUN_SCOUT_PRIMARY = 71
BAT_FISH = 72
CROSSBOW = 73
STICKBOMB = 74
HANDGUN_SCOUT_SEC = 75
SODA_POPPER = 76
SNIPERRIFLE_DECAP = 77
RAYGUN = 78
PARTICLE_CANNON = 79
MECHANICAL_ARM = 80
DRG_POMSON = 81
BAT_GIFTWRAP = 82
GRENADE_ORNAMENT = 83
RAYGUN_REVENGE = 84
PEP_BRAWLER_BLASTER = 85
CLEAVER = 86
GRENADE_CLEAVER = 87
STICKY_BALL_LAUNCHER = 88
GRENADE_STICKY_BALL = 89
SHOTGUN_BUILDING_RESCUE = 90
CANNON = 91
THROWABLE = 92
GRENADE_THROWABLE = 93
PDA_SPY_BUILD = 94
GRENADE_WATERBALLOON = 95
HARVESTER_SAW = 96
SPELLBOOK = 97
SPELLBOOK_PROJECTILE = 98
SNIPERRIFLE_CLASSIC = 99
PARACHUTE = 100
GRAPPLINGHOOK = 101
PASSTIME_GUN = 102
CHARGED_SMG = 103
BREAKABLE_SIGN = 104
ROCKETPACK = 105
SLAP = 106
JAR_GAS = 107
GRENADE_JAR_GAS = 108
FLAME_BALL = 109


# ============================================================================
# >> EVENTS
# ============================================================================
@Event('player_hurt')
def on_player_hurt(game_event):
"""Game event fired when a player receives damage."""

# Get the weapon type causing the damage...
weapon_type = TF2_WeaponType(game_event.get_int('weaponid'))


Zeus wrote:Yeah im not sure why player shoot does not trigger. I was gonna ask about that lol. Im assuming there is just some offset not set right?

Even if the events are declared, this is up to the game to fire them. Source.Python only listen for the fired events and call the registered callbacks that matches the name. I'm pretty sure player_shoot is some old event from HL2 that is carried in the SDK and is never used by any later games.


I suppose that works. I would've liked to see that be a bit more dynamic than that but if that's what sourcemod is doing then thats prob fine.
Is there a clean namespace we could use to integrate this directly into the SourcePython? Theres a handful of other TF2 related data that would be helpful to have, such as classid's to class name, or team id to team name.
User avatar
L'In20Cible
Project Leader
Posts: 1533
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: TF2 - Getting weapon names from event byte

Postby L'In20Cible » Tue Sep 04, 2018 4:27 pm

Zeus wrote:I suppose that works. I would've liked to see that be a bit more dynamic than that but if that's what sourcemod is doing then thats prob fine.
Is there a clean namespace we could use to integrate this directly into the SourcePython? Theres a handful of other TF2 related data that would be helpful to have, such as classid's to class name, or team id to team name.

Hmm. I just had a look and seems I added them as weapons.constants.WeaponID back in 2015. The variable name being "weaponid" was making it quite obvious but I had no memory of playing with that at all. The following should do it:

Syntax: Select all

from weapons.constants import WeaponID

weapon_id = WeaponID(game_event.get_int('weaponid'))

Some values are missing, and some others might have changed. Feel free to validate them and submit a pull request with changes if you want. :smile:
User avatar
Zeus
Member
Posts: 52
Joined: Sat Mar 24, 2018 5:25 pm
Location: Chicago
Contact:

Re: TF2 - Getting weapon names from event byte

Postby Zeus » Tue Sep 04, 2018 4:59 pm

L'In20Cible wrote:
Zeus wrote:I suppose that works. I would've liked to see that be a bit more dynamic than that but if that's what sourcemod is doing then thats prob fine.
Is there a clean namespace we could use to integrate this directly into the SourcePython? Theres a handful of other TF2 related data that would be helpful to have, such as classid's to class name, or team id to team name.

Hmm. I just had a look and seems I added them as weapons.constants.WeaponID back in 2015. The variable name being "weaponid" was making it quite obvious but I had no memory of playing with that at all. The following should do it:

Syntax: Select all

from weapons.constants import WeaponID

weapon_id = WeaponID(game_event.get_int('weaponid'))

Some values are missing, and some others might have changed. Feel free to validate them and submit a pull request with changes if you want. :smile:


Oh awesome! I'll def have a PR for ya on that one!

Return to “Plugin Development Support”

Who is online

Users browsing this forum: No registered users and 26 guests