Error on take_damage

Please post any questions about developing your plugin here. Please use the search function before posting!
existenz
Member
Posts: 39
Joined: Thu Feb 09, 2017 3:33 pm

Error on take_damage

Postby existenz » Mon Feb 27, 2017 7:53 pm

Hey.

I have an error on take damage.

Syntax: Select all

@EntityPreHook(EntityCondition.is_player, 'on_take_damage')
def _pre_damage_call_events(stack_data):
take_damage_info = make_object(TakeDamageInfo, stack_data[1])

if not take_damage_info.attacker:
return

entity = Entity(take_damage_info.attacker)
attacker = g_players[userid_from_index(entity.index)] if entity.is_player() else None
victim = g_players[userid_from_pointer(stack_data[0])]

event_args = {
'attacker': attacker,
'victim': victim,
'take_damage_info': take_damage_info,
}

if attacker:
if victim.team == attacker.team:
attacker.hero.call_events('player_pre_teammate_attack', player=attacker,
**event_args)
victim.hero.call_events('player_pre_teammate_victim', player=victim, **event_args)
return

attacker.hero.call_events('player_pre_attack', player=attacker, **event_args)
victim.hero.call_events('player_pre_victim', player=victim, **event_args)


Call :

Syntax: Select all

_poisoned = set()

@property
def _poison_damage(self):
return 1 + self.level

@property
def _poison_chance(self):
return 16 + (2 * self.level)

@events('player_attack')
def _on_player_attack(self, attacker, victim, **eargs):
if randint(1, 100) > self._poison_chance or victim.userid in self._poisoned:
return

self._poisoned.add(victim.userid)

for index in attacker.weapon_indexes():
break
else:
index = None

Delay(1, victim.take_damage, (self._poison_damage, attacker.index, index))
Delay(2, victim.take_damage, (self._poison_damage, attacker.index, index))
Delay(3, victim.take_damage, (self._poison_damage, attacker.index, index))
Delay(4, victim.take_damage, (self._poison_damage, attacker.index, index))
Delay(5, victim.take_damage, (self._poison_damage, attacker.index, index))
Delay(6, victim.take_damage, (self._poison_damage, attacker.index, index))
Delay(7, self._poisoned.discard, (victim.userid,))


Syntax: Select all

[SP] Caught an Exception:
Traceback (most recent call last):
File "../addons/source-python/packages/source-python/listeners/tick.py", line 76, in _tick
self.pop(0).execute()
File "../addons/source-python/packages/source-python/listeners/tick.py", line 170, in execute
return self.callback(*self.args, **self.kwargs)
File "../addons/source-python/packages/source-python/entities/_base.py", line 1019, in take_damage
take_damage_info.attacker = attacker_index

ValueError: Conversion from "Index" (166) to "BaseHandle" failed.
User avatar
Ayuto
Project Leader
Posts: 1541
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Re: Error on take_damage

Postby Ayuto » Mon Feb 27, 2017 8:17 pm

The error is probably caused by these lines:

Syntax: Select all

Delay(1, victim.take_damage, (self._poison_damage, attacker.index, index))
Delay(2, victim.take_damage, (self._poison_damage, attacker.index, index))
Delay(3, victim.take_damage, (self._poison_damage, attacker.index, index))
Delay(4, victim.take_damage, (self._poison_damage, attacker.index, index))
Delay(5, victim.take_damage, (self._poison_damage, attacker.index, index))
Delay(6, victim.take_damage, (self._poison_damage, attacker.index, index))
Delay(7, self._poisoned.discard, (victim.userid,))
At the time the delay is executed, the index stored in "index" probably doesn't exist anymore.

Btw. you are not calling take_damage correctly. The second argument is the damage type, but you are passing a player index:
http://wiki.sourcepython.com/developing ... ake_damage
existenz
Member
Posts: 39
Joined: Thu Feb 09, 2017 3:33 pm

Re: Error on take_damage

Postby existenz » Mon Feb 27, 2017 8:34 pm

Oh yes my bad. If I precise attacker_index and weapon_index it should work ?
But i don't understand the problem of index.
What happens if I put DamageType poison ?
User avatar
Ayuto
Project Leader
Posts: 1541
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Re: Error on take_damage

Postby Ayuto » Mon Feb 27, 2017 9:17 pm

existenz wrote:Oh yes my bad. If I precise attacker_index and weapon_index it should work ?
But i don't understand the problem of index.

Your "index" variable stores the index of a weapon of the attacker. Then you create a delay to deal damage to the victim using that index. But when the delay is executed, the weapon might not exist anymore (e.g. because it has been removed due to a new round). This issue can also happen with the victim and the attacker. That means you need to validate that these indexes still exist, when the delay gets executed. Ideally, you also check that they are still the same entities, because during the delay and entity could have been replaced.

Long story short: you will need something like this:

Syntax: Select all

victim_handle = victim.inthandle
attacker_handle = attacker.inthandle
if index is not None:
weapon_handle = inthandle_from_index(index)

Delay(1, deal_damage, (victim_handle, self._poison_damage, attacker_handle, weapon_handle)
Delay(2, deal_damage, (victim_handle, self._poison_damage, attacker_handle, weapon_handle))
Delay(3, deal_damage, (victim_handle, self._poison_damage, attacker_handle, weapon_handle))
Delay(4, deal_damage, (victim_handle, self._poison_damage, attacker_handle, weapon_handle))
Delay(5, deal_damage, (victim_handle, self._poison_damage, attacker_handle, weapon_handle))
Delay(6, deal_damage, (victim_handle, self._poison_damage, attacker_handle, weapon_handle))
Delay(7, _poisoned.discard, (victim.userid,))


def deal_damage(victim_handle, damage, attacker_handle, weapon_handle):
try:
victim = Player(index_from_inthandle(victim_handle))
except ValueError:
return

try:
attacker_index = index_from_inthandle(attacker_handle)
except ValueError:
# Not sure if you wish to abort at this point or continue...
attacker_index = None

if weapon_handle is not None:
try:
weapon_index = index_from_inthandle(weapon_handle)
except ValueError:
# Not sure if you wish to abort at this point or continue...
weapon_index = None
else:
weapon_index = None

victim.take_damage(
damage,
attacker=attacker_index,
weapon=weapon_index)


existenz wrote:What happens if I put DamageType poison ?

I don't know. Go ahead and test it. :tongue:
existenz
Member
Posts: 39
Joined: Thu Feb 09, 2017 3:33 pm

Re: Error on take_damage

Postby existenz » Mon Feb 27, 2017 9:45 pm

I had not thought about that. Thanks :)
existenz
Member
Posts: 39
Joined: Thu Feb 09, 2017 3:33 pm

Re: Error on take_damage

Postby existenz » Tue Feb 28, 2017 8:48 am

Hmm i have an invalid syntax on deal_damage.
You mean take_damage ?
User avatar
L'In20Cible
Project Leader
Posts: 914
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: Error on take_damage

Postby L'In20Cible » Tue Feb 28, 2017 8:59 am

deal_damage is in your code:

Syntax: Select all

def deal_damage(victim_handle, damage, attacker_handle, weapon_handle):
existenz
Member
Posts: 39
Joined: Thu Feb 09, 2017 3:33 pm

Re: Error on take_damage

Postby existenz » Tue Feb 28, 2017 9:08 am

I didn't see that i can scroll ...
I m sorry. I will try.
existenz
Member
Posts: 39
Joined: Thu Feb 09, 2017 3:33 pm

Re: Error on take_damage

Postby existenz » Tue Feb 28, 2017 9:37 am

Thanks. That's work very well :D
User avatar
L'In20Cible
Project Leader
Posts: 914
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: Error on take_damage

Postby L'In20Cible » Tue Feb 28, 2017 12:14 pm

There is also a "Select all" option as header of the code block. ;)
existenz
Member
Posts: 39
Joined: Thu Feb 09, 2017 3:33 pm

Re: Error on take_damage

Postby existenz » Tue Feb 28, 2017 1:12 pm

Yes. I was tired ... XD

Return to “Plugin Development Support”

Who is online

Users browsing this forum: No registered users and 1 guest