Preventing death event take_damage

Please post any questions about developing your plugin here. Please use the search function before posting!
arawra
Senior Member
Posts: 149
Joined: Fri Jun 21, 2013 6:51 am

Preventing death event take_damage

Postby arawra » Tue May 22, 2018 2:29 am

When using take_damage it will cause two death notifications and fire player_death twice, once for each weapon. How do I prevent that?

Image

I wouldn't mind preHooking on_take_damage and modifying damage, but I do not know how to access the attacker's information. The only information that seemed to be returned was the victim and damage information pointers.


Edit: The issue also seems to only occur on headshots.
User avatar
satoon101
Project Leader
Posts: 2539
Joined: Sat Jul 07, 2012 1:59 am

Re: Preventing death event take_damage

Postby satoon101 » Tue May 22, 2018 2:45 am

You can get the attacker's information from the TakeDamageInfo.
http://wiki.sourcepython.com/developing ... o.attacker


You can also get the weapon used in the attack.
http://wiki.sourcepython.com/developing ... nfo.weapon
Image
arawra
Senior Member
Posts: 149
Joined: Fri Jun 21, 2013 6:51 am

Re: Preventing death event take_damage

Postby arawra » Tue May 22, 2018 3:23 am

How would I get that information from an event prehook?
User avatar
satoon101
Project Leader
Posts: 2539
Joined: Sat Jul 07, 2012 1:59 am

Re: Preventing death event take_damage

Postby satoon101 » Tue May 22, 2018 4:13 am

It's not an "event" pre-hook, it's pre-hooking a function in memory. Events just notify you that some is happening (or primarily 'has' happened). You can hook events, but the effect of doing that is very limited. Here is how you could hook the OnTakeDamage function and get the attacker's info, as well as adjust the damage done:

Syntax: Select all

from entities import TakeDamageInfo
from entities.constants import DamageTypes
from entities.entity import Entity
from entities.hooks import EntityCondition, EntityPreHook
from memory import make_object
from players.entity import Player
from weapons.entity import Weapon

@EntityPreHook(EntityCondition.is_bot_player, 'on_take_damage')
@EntityPreHook(EntityCondition.is_human_player, 'on_take_damage')
def _pre_take_damage(stack_data):
take_damage_info = make_object(TakeDamageInfo, stack_data[1])
attacker = Entity(take_damage_info.attacker)
if attacker.classname != 'player':
return

attacker = Player(attacker.index)
weapon = Weapon(take_damage_info.weapon)

# Only allow knife damage
if weapon.classname != 'weapon_knife':
return

# Increase the damage
take_damage_info.damage += 100

# Change the type of damage
take_damage_info.type = DamageTypes.BURN

# Add a damage type
take_damage_info |= DamageTypes.POISON
Image
arawra
Senior Member
Posts: 149
Joined: Fri Jun 21, 2013 6:51 am

Re: Preventing death event take_damage

Postby arawra » Wed May 23, 2018 4:14 am

I couldn't help but notice there wasn't a way to access the victim in this case...?

E: OK so on this post you can
viewtopic.php?f=20&t=1468&p=11709&hilit=on_take_damage#p11709

How can you find out what is returned in stack_data?
arawra
Senior Member
Posts: 149
Joined: Fri Jun 21, 2013 6:51 am

Re: Preventing death event take_damage

Postby arawra » Sun Jun 03, 2018 7:08 am

I'm not finding it possible to modify players' health who are not contained in the pointer argument.

Attempts to use player.take_damage even with skip_hooks=True also always results in a crash.

Syntax: Select all

@SayCommand('test')
def test(command, index, teamOnly):
message(Player(index).get_view_player().health)
# Using this to test the intended target's HP


@EntityPreHook(EntityCondition.is_human_player, 'on_take_damage')
def _pre_take_damage(stack_data):
take_damage_info = make_object(TakeDamageInfo, stack_data[1])
attacker = Entity(take_damage_info.attacker)

if attacker.classname == 'player':
weapon = Weapon(take_damage_info.weapon)
if weapon.classname != 'worldspawn':


victimObject = make_object(Player, stack_data[0])
victim = playerList[victimObject.index]
attacker = playerList[attacker.index]


damage = take_damage_info.damage
p1 = attacker.origin
p2 = victim.origin
distance = math.sqrt(abs(p2[0]**2 - p1[0]**2) + abs(p2[1]**2 - p1[1]**2) + abs(p2[2]**2 - p1[2]**2))
if attacker.getClass() == 'Ranger':
message('ranger')
attacker.speedChange(.05 * attacker.getLevel(), 3)
if True: #attacker.pierce:

message('pierce on')
for cleavedTarget in PlayerIter():
if not cleavedTarget.playerinfo.is_dead() and cleavedTarget.playerinfo.team != attacker.playerinfo.team and cleavedTarget.index != victim.index:

p3 = cleavedTarget.origin
# p1 = attacker, p2 = victim, p3 = cleave target
top = (p2[0] - p1[0]) * (p3[0]-p1[0]) + (p2[1]-p1[1]) * (p3[1]-p1[1])
bottom1 = math.sqrt( (p2[0]-p1[0])**2 + (p2[1]-p1[1])**2)
bottom2 = math.sqrt((p3[0]-p1[0])**2 + (p3[1]-p1[1])**2)
try:
if math.acos( top/(bottom1*bottom2) ) * 180/math.pi < 15:
message("Damaging " + cleavedTarget.name)
cleavedTarget.health - damage # This line does not do anything

except:
pass

if victim.getClass() == 'Paladin':
while victim.armor:
if damage <= 0: break
victim.armor -= 1
damage -= 1


take_damage_info.damage = damage
return
User avatar
satoon101
Project Leader
Posts: 2539
Joined: Sat Jul 07, 2012 1:59 am

Re: Preventing death event take_damage

Postby satoon101 » Tue Jun 05, 2018 4:52 pm

Syntax: Select all

cleavedTarget.health - damage # This line does not do anything

That's because you aren't actually setting anything there. You need to use -= not just -
Image

Return to “Plugin Development Support”

Who is online

Users browsing this forum: Baidu [Spider] and 4 guests