Skip to content

OnPlayerHitScenery

A player’s melee blow struck the level itself - a tree, a rock, a wall.

The player’s own game saw their blade (or fist) meet the level rather than a body, and says what it met - named the way a client script’s GetLookTarget names a look. Once a swing at most; the server checks that the point is within the drawn weapon’s reach of the player, then calls this. Nothing else happens: whether a blow on a tree chops it, plays a sound or does nothing is the mode’s.

The game decides what a blade meets: a trunk, a rock or a wall, yes - a swing at the bare ground lands nowhere and calls nothing, and a player standing right up against a big rock or a wall gets the game’s own refusal (the cross on the crosshair) until they step back.

hit has kind ("terrain", "static" - a building, a wall, a rock -, "vegetation" - a tree or a bush, and many of the level’s small stones - or "object", a level object with a script), x, y, z (the point struck, metres), normal ({x, y, z}), surface (the game’s surface type: "mat_wood", "mat_rock" …) and weapon (the drawn weapon by its table name, "fists" without one). A tree, a bush or a piece of scenery also has mesh (the model, lower case - its folder is a tree’s species), bbox ({min = {x, y, z}, max = {x, y, z}}) and center: the mesh and the centre are what RemoveLevelObject takes to take it away. mesh is nil when the game cannot tell which piece of the level was struck. An object has name (its level name - a door’s or a chest’s key) and class.

It is the player’s game’s word: a modified game could report a blow that never happened, within the weapon’s reach of where the player stands. Count blows, add a cooldown, and check the rest as you would any input from a player.

function OnPlayerHitScenery(pid, hit)
-- ...
end
Parameter Type
pid number the player
hit table {kind, x, y, z, normal, surface, weapon, mesh, bbox, center, name, class}

nothing

-- a woodcutter: the game's own chop at the bark, and a tree felled after five blows of an axe
local blows = {}
function OnPlayerHitScenery(pid, hit)
if not (hit.mesh and hit.mesh:find("/trees/normal_trees/")) then return end
PlaySound("f_lu_axe_log" .. math.random(3), hit.x, hit.y, hit.z, 3)
if not hit.weapon:lower():find("axe") then return end
local key = string.format("%s@%.1f,%.1f", hit.mesh, hit.center.x, hit.center.y)
blows[key] = (blows[key] or 0) + 1
if blows[key] >= 5 then
blows[key] = nil
RemoveLevelObject("vegetation", hit.center.x, hit.center.y, hit.center.z, {mesh = hit.mesh, persist = false})
end
end

RemoveLevelObject · PlaySound · OnMeleeHitZone · the Combat group of the index