Skip to content

OnPlayerDamage

The server accepted a hit on a player - change the damage, cancel it, or let it through.

Called before the damage comes off the health. attacker is the pid who struck, or -1 for damage without one (an NPC actor’s blow when the mode has no OnActorAttack, SetPlayerHealth). zone is the attack zone the attacker’s game recorded; part the body part struck, 1 .. 6 (0 unknown; GetBodyPartName); weapon the attacker’s weapon by its table name (shortswordBroad, bow_c + arrow_normal; "" bare-handed or without the tables); dtype "stab", "slash", "smash" or ""; bleeds whether the blow opens a bleeding wound by the server’s rules (SetBleedRules: a cut the armour let enough of through) and armour the share of it the armour on that part took (0 .. 0.85). Return a number to change the damage (0 cancels the hit, so do a stamina cost, an injury and a bleed), false to cancel it, nothing to keep it - and a second value true / false to decide the bleeding yourself (return nil, false keeps the damage and opens no wound). Hits between teammates never get here, nor a swing the victim met with a perfect block or blocked on their own screen; a master strike’s counter does, with the defender as attacker (the torso, × [combat] master_strike_scale), and so does a blow inside a clinch (the torso, × [combat] clinch_scale) unless the victim countered it. Two players clinch only while [combat] clinch and [combat] pvp are on, in the same virtual world, already in a fight, within three metres, neither riding, and not within a second of the end of their last clinch. A melee hit between two players is judged on the victim’s screen: it comes when the victim’s game says the blow landed - a moment after it did on the attacker’s screen - with the body part it struck there; a blow the attacker saw land that the victim’s game never shows within [combat] verdict_window_ms is a miss (unanswered_blow). A player whose game has judged no blow yet this session (a bot) is hit as the attacker saw it, up to parry_window_ms after the blow (counter_parry_window_ms for a counter); a clinch blow waits up to clinch_parry_window_ms for the victim’s counter (the Combat guide).

function OnPlayerDamage(pid, attacker, damage, zone, part, weapon, dtype, bleeds, armour)
-- ...
end
Parameter Type
pid number the victim
attacker number who struck; -1 = nobody
damage number what the victim is about to lose
zone number the attack zone the attacker’s game recorded
part number the body part struck, 1 .. 6; 0 unknown
weapon string the weapon’s table name; "" bare-handed
dtype string "stab", "slash", "smash" or ""
bleeds boolean whether the blow opens a bleeding wound by the server’s rules (SetBleedRules)
armour number the share of the blow the armour on the struck part took, 0 .. 0.85

a number replaces the damage (0 cancels); false cancels the hit; nothing keeps it. A second value true / false decides the bleeding

-- no damage in the lobby, double to the head, a log line for a big one, no bleeding in a training duel
function OnPlayerDamage(pid, attacker, damage, zone, part, weapon, dtype, bleeds, armour)
if IsPlayerInZone(pid, lobby) then return false end
if part == BODY_PART_HEAD then damage = damage * 2 end
if damage > 40 and attacker >= 0 then
Log(string.format("%s hit %s for %.0f with %s (%s, armour took %.0f%%)", GetPlayerName(attacker), GetPlayerName(pid), damage,
weapon, dtype, armour * 100))
end
if IsPlayerInZone(pid, trainingYard) then return damage, false end
return damage
end

OnPlayerInjury · OnPlayerDeath · OnActorDamage · GetBodyPartName · SetPlayerTeam · SetBleedRules · the Combat group of the index