Stats
Needs the internal running and needs_internal = true in script_info.
p:get_stats() -> table | nilReturns the player's combat stats with every item and modifier applied. Works on any player object, not just the local player. Percent fields are percentages: 18.0 means 18 percent.
Keys on every player
| Key | Meaning | Unit |
|---|---|---|
max_health | Max health | HP |
bullet_resist | Bullet damage reduction | percent |
spirit_resist | Spirit damage reduction | percent |
melee_resist | Melee damage reduction | percent |
debuff_resist | Debuff resist | percent |
bullet_shield | Shield pool in front of health | HP |
barrier | Pool that soaks every damage type | HP |
crit_taken_scale | Crit damage received | multiplier, 1.0 baseline |
slow_resist | Slow resistance | percent |
ability_level | Ability level stat | number |
dmg_taken_inc | All damage taken increase | percent |
bullet_dmg_taken_inc | Bullet damage taken increase | percent |
spirit_dmg_taken_inc | Spirit damage taken increase | percent |
dmg_taken_red | All damage taken reduction | percent |
bullet_dmg_red_pct | Bullet damage reduction | percent |
ability_dmg_red_pct | Ability damage reduction | percent |
seq | Changes when any row in the feed was refreshed | integer |
entry_seq | Changes when this row was refreshed | integer |
The six dmg_taken_inc and dmg_taken_red keys are rarely non zero.
Keys on the local player only
Only present on the local player. On anyone else they are absent, not zero, so test with if s.bullet_damage ~= nil.
weapon_power_bonus, spirit_power, bullet_damage, fire_rate_bonus, clip_size, health_regen, move_speed, light_melee, heavy_melee, bullet_lifesteal, spirit_lifesteal, falloff_min, falloff_max
weapon_power_bonusandfire_rate_bonusare bonuses over the hero base, so 0 is the baseline.bullet_damageis damage per bullet before resists and falloff.falloff_minandfalloff_maxare in game units.p:get_distance()is in metres; multiply by 39.37 to compare.
Returns nil when
- the internal is not running
needs_internal = trueis missing- nothing called
p:get_stats()in the last 2 seconds. The feed idles, and the first call after a gap returnsnilwhile it starts again - the player is not in the feed yet
- the player is dead. The local player stays in the feed while dead
Notes
- Rows refresh within 100 ms.
- The same table is returned until
entry_seqchanges. Do not write into it; other scripts get the same table. - 16 players maximum.
- No visibility requirement.
Example
Bullets to kill on the nearest enemy, from Shots to Kill:
function on_tick()
local x, y = 40, 460
local function line(t, c, sc) draw.text(x, y, t, c or WHITE, sc or 1.15); y = y + 18 end
if not internal.is_loaded() then line("shots_to_kill: internal not loaded", DIM); return end
local me = local_player and local_player() or nil
local ms = me and me:get_stats() or nil
if not ms or not ms.bullet_damage then line("shots_to_kill: waiting for local stats", DIM); return end
local e, d = nearest_enemy()
local es = e and e:get_stats() or nil
if not e or not es then line("shots_to_kill: no enemy stats yet", DIM); return end
local B = ms.bullet_damage
local R = (es.bullet_resist or 0) / 100
local inc = ((es.dmg_taken_inc or 0) + (es.bullet_dmg_taken_inc or 0)) / 100
local red = ((es.dmg_taken_red or 0) + (es.bullet_dmg_red_pct or 0)) / 100
local per = B * (1 - R) * (1 + inc) * (1 - red)
if per < 0.1 then line("shots_to_kill: per-hit damage ~0", DIM); return end
local pool = (e:get_health() or es.max_health or 0) + (es.bullet_shield or 0) + (es.barrier or 0)
line(string.format("%d body", math.ceil(pool / per)), GREEN, 1.4)
endbullet_damage is only on your own row and the resists are on the enemy's, so either read can be nil while the other answers. nearest_enemy is a helper defined in that script. For headshots, a multiplier of about 1.65 is an observed value, not something the API returns.