cmd
The cmd object is the movement command of the current tick. It is passed to the callbacks of the pre_movement, post_movement and createmove events. Writing fields changes the command the game will send to the server right away.
cmdpoints to the live command. If you keep the object and write to it later, the write goes into the command of the tick in which it happens. Usecmd:new()for an independent copy.
Fields#
| Field | Read | Write |
|---|---|---|
legacy_command_number |
number |
forbidden: error field is read-only |
client_tick |
number |
number |
viewangles |
angle — a reference to the command angles: cmd.viewangles.y = ... writes straight into the command |
angle |
moveangles |
angle — a reference to the movement angles |
angle |
forwardmove, leftmove, upmove |
number |
number |
impulse, weaponselect, random_seed, mousedx, mousedy |
number |
number (integer) |
camera |
boolean — camera turn flag, see below |
boolean |
IN_* |
button: number 0–7 or nil |
number 0–7 |
- An unknown field reads as
nil; writing to it is the errorinvalid field. - A value of the wrong type — error
number expected,angle expectedorboolean expected.
events.createmove:set(function(cmd)
print(cmd.legacy_command_number, " ", cmd.client_tick, " ", cmd.viewangles)
end)
IN_* buttons#
Each button is a field named after the game button enumeration: IN_ATTACK, IN_ATTACK2, IN_JUMP, IN_DUCK, IN_FORWARD, IN_BACK, IN_USE, IN_RELOAD and others. The name is case-sensitive.
The value is a number of three bits:
| Bit | Meaning |
|---|---|
| 1 | the button is held |
| 2 | the state changed in this tick |
| 4 | scroll |
If there is no button with this name — nil. On write the bits set all three button states.
-- Do not shoot while the player is in the air
events.createmove:set(function(cmd)
local me = entity.local_pawn()
if not me then return end
local on_ground = me.m_hGroundEntity ~= nil
if not on_ground and bit.band(cmd.IN_ATTACK or 0, 1) ~= 0 then
cmd.IN_ATTACK = 0
end
end)
cmd.camera#
The "turn the camera to the command angles" flag. If you write cmd.camera = true, the cheat turns the player's real camera to cmd.viewangles — to the angles that were in the command at the moment of the write.
| Read | Write |
|---|---|
boolean |
boolean; true — turn the camera, false — clear the flag |
- Angles first, then the flag. The flag remembers
cmd.viewanglesat the moment of the write; angles changed afterwards are not used. - When it is applied. Written in
pre_movement— after thepre_movementdispatch and once more afterpost_movement; written inpost_movement— afterpost_movement; written increatemove— right after thecreatemovedispatch. - The flag lasts one tick. It is reset before every
pre_movement, so write it every tick to keep the camera. - Safe Mode. If Safe Mode does not allow turning the camera on the current server, the flag is not raised: writing
truedoes nothing, reading returnsfalse.
After the turn the camera keeps looking along the new angles — the mouse moves it from there.
-- Throw a grenade straight up on the Z key (VK 0x5A): a grenade must be in hand
local PULL_TICKS, HOLD_TICKS = 8, 24
local state, ticks, key_was = "idle", 0, false
local NADES = { C_HEGrenade = true, C_Flashbang = true, C_SmokeGrenade = true, C_MolotovGrenade = true, C_IncendiaryGrenade = true, C_DecoyGrenade = true }
events.createmove:set(function(cmd)
local key_now = utils.key_state(0x5A)
local pressed = key_now and not key_was
key_was = key_now
if state == "idle" then
local me = entity.local_pawn()
local w = me and me:is_alive() and me:weapon()
if not pressed or not w or not NADES[w:classname()] then return end
state, ticks = "pull", 0
end
cmd.viewangles.x = -89 -- angles first
cmd.camera = true -- then the flag: the camera turns to them
if state == "pull" then -- hold attack: pull the pin
cmd.IN_ATTACK = (ticks == 0) and 3 or 1
ticks = ticks + 1
if ticks >= PULL_TICKS then state, ticks = "release", 0 end
else -- release and keep the angles until the grenade leaves
cmd.IN_ATTACK = (ticks == 0) and 2 or 0
ticks = ticks + 1
if ticks >= HOLD_TICKS then state = "idle" end
end
end)
cmd:buttons()#
The three button masks of the command.
Returns: 64-bit integers value, changed, scroll — held, changed, scroll.
events.pre_movement:set(function(cmd)
local value, changed = cmd:buttons()
if value ~= 0 then
-- at least one button is held
end
end)
cmd:new()#
A copy of the command. Writing to the copy does not affect the game.
Returns: cmd.
events.pre_movement:set(function(cmd)
local copy = cmd:new()
copy.forwardmove = 0 -- the game will not see this
print(cmd.forwardmove) -- the original value
end)
cmd:finalize()#
Finalizes the command subticks in place.
Returns: nothing.
events.createmove:set(function(cmd)
cmd:finalize()
end)
cmd:finalized()#
A copy of the command with finalized subticks. The original command does not change.
Returns: cmd.
events.pre_movement:set(function(cmd)
local fin = cmd:finalized()
print(fin.forwardmove)
end)