OnPhysicalAttacked
The script attached to this event fires each time the object is attacked by a physical attack (claws, sword, fists, bow, etc.). This could be used for a reaction to the attack such as changing weapons, fleeing, surrendering, etc.
The event also fires for taunts and animal empathy skills used against the creature (this is so the AI will start attacking if they're not already). This is slightly bugged since it doesn't reset any of the parameters except the last attacker - see GetLastAttackType which overlaps the previous value.
Trigger
A physical attack is brought against a creature, door, or placeable object (bow, claw, fist, sword, etc.), or taunt or animal empathy skills are used against a creature. It doesn't need to be hit or damaged to trigger it. You can track damage events in OnDamaged excepting cases where the object is plot (meaning no damage events are fired), 0 damage done should still trigger OnDamaged.
Function(s)
This event is signalled with one or more of these being valid:
- GetLastAttacker - Who attacked us
- GetLastWeaponUsed(oAttacker) - What weapon was used (or OBJECT_INVALID if fists) by the attacker
- GetLastAttackType(OBJECT_SELF) - What attack type was used, if any, against us
- GetLastAttackMode(oAttacker) - What attack mode was used, if any, by the attacker
Usually the default AI runs DetermineCombatRound(object, int) for standard combat round actions.
Remarks
If a creature is attacked and not currently in combat, it goes hostile and emits appropriate shouts to alert allies nearby. It should also be possible to use this routine to allow a member of a non hostile faction to issue a warning to a PC that attacked them, going hostile only on a second attack. At least that seems to be the purpose of the 'NW_FLAG_SET_WARNINGS' flag found in the on spawn routine. However, because the code that makes the faction and allied faction members hostile to the offending player is hard-coded into the engine itself, it is impossible to know for sure why a particular creature has become hostile. As such there seems to be no easy way to actually get this functionality working.
This event is really well used in any kind of archery content/dummy attacking/hitting something, as it fires even if the attacker doesn't damage it. Also, as placeables have an effective AC of 0, meaning only a definite miss (a roll of 1 on the d20) will not hit it, should mean that almost all attacks against placeables have landed home.
Example
// physical attacked event.
void main()
{
// Get attacker, and the other parts.
object oAttacker = GetLastAttacker();
// Get the last weapon used to hit us, IE: From this attack.
// * Most useful for dissolving enemy weapons/taking them/disarming
// them, but very very evil if you do
object oWeapon = GetLastWeaponUsed(oAttacker);
// Returns COMBAT_MODE_*, so perhaps parry, or rapid shot.
// * These are "always on" and togglable, of course.
int nMode = GetLastAttackMode(oAttacker);
// Returns SPECIAL_ATTACK_*, so if anything, a usable feat
// like knockdown, disarm and so on.
// NOTE: You need to pass OBJECT_SELF into this to correctly
// determine the attack type (ignore the toolset description)
int nAttackType = GetLastAttackType();
// If they used a weapon tagged as "HEAL_THE_MONSTER", we
// are healed 40 hit points
if(GetTag(oWeapon) == "HEAL_THE_MONSTER")
{
effect eHeal = EffectHeal(40);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eHeal, OBJECT_SELF);
}
// If they used expertise or the improved version, we need more
// attack, we add +5 or +10 to hit them easier, for 6 seconds.
if(nMode == COMBAT_MODE_IMPROVED_EXPERTISE)
{
// Apply +10 attack
effect eAttack10 = EffectAttackIncrease(10);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eAttack10, OBJECT_SELF, 6.0);
}
else if(nMode == COMBAT_MODE_EXPERTISE)
{
// Apply +5 attack
effect eAttack5 = EffectAttackIncrease(5);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eAttack5, OBJECT_SELF, 6.0);
}
// If they made an attempt at knockdown, we add +10 discipline
// for 12 seconds.
if(nAttackType == SPECIAL_ATTACK_KNOCKDOWN ||
nAttackType == SPECIAL_ATTACK_IMPROVED_KNOCKDOWN)
{
// Apply +10 discipline
effect eSkill = EffectSkillIncrease(10, SKILL_DISCIPLINE);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eSkill, OBJECT_SELF, 12.0);
}
}
See Also
functions: |
GetLastAttacker GetLastWeaponUsed GetLastAttackType GetLastAttackMode |