CS2 Lua API

cmd

Объект cmd — команда движения текущего тика. Его получают колбэки событий pre_movement, post_movement и createmove. Записи в поля сразу меняют команду, которую игра отправит на сервер.

cmd указывает на живую команду. Если сохранить объект и записать в него позже, запись уйдёт в команду того тика, в котором она выполнена. Для независимой копии используйте cmd:new().

Поля#

Поле Чтение Запись
legacy_command_number number запрещена: ошибка field is read-only
client_tick number number
viewangles angle — ссылка на углы команды: cmd.viewangles.y = ... пишет прямо в команду angle
moveangles angle — ссылка на углы движения angle
forwardmove, leftmove, upmove number number
impulse, weaponselect, random_seed, mousedx, mousedy number number (целое)
camera boolean — флаг поворота камеры, см. ниже boolean
IN_* кнопка: number 0–7 или nil number 0–7
  • Неизвестное поле читается как nil, запись в него — ошибка invalid field.
  • Значение не того типа — ошибка number expected, angle expected или boolean expected.
events.createmove:set(function(cmd)
    print(cmd.legacy_command_number, " ", cmd.client_tick, " ", cmd.viewangles)
end)

Кнопки IN_*#

Каждая кнопка — поле с именем из перечисления кнопок игры: IN_ATTACK, IN_ATTACK2, IN_JUMP, IN_DUCK, IN_FORWARD, IN_BACK, IN_USE, IN_RELOAD и другие. Регистр важен.

Значение — число из трёх битов:

Бит Значение
1 кнопка зажата
2 состояние изменилось в этом тике
4 прокрутка (scroll)

Если кнопки с таким именем нет — nil. При записи биты задают все три состояния кнопки.

-- Не стрелять, пока игрок в воздухе
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#

Флаг «повернуть камеру к углам команды». Если записать cmd.camera = true, чит повернёт настоящую камеру игрока к cmd.viewangles — к тем углам, которые были в команде в момент записи.

Чтение Запись
boolean boolean; true — повернуть камеру, false — снять флаг
  • Сначала углы, потом флаг. Флаг запоминает cmd.viewangles на момент записи; углы, изменённые после, не учитываются.
  • Когда применяется. Записанный в pre_movement — после раздачи pre_movement и ещё раз после post_movement; записанный в post_movement — после post_movement; записанный в createmove — сразу после раздачи createmove.
  • Флаг действует один тик. Он сбрасывается перед каждым pre_movement, поэтому, чтобы держать камеру, записывайте его каждый тик.
  • Safe Mode. Если Safe Mode не разрешает поворот камеры на текущем сервере, флаг не поднимается: запись true ничего не делает, чтение возвращает false.

После поворота камера остаётся смотреть по новым углам — мышь дальше ведёт её оттуда.

-- Бросок гранаты вверх по клавише Z (VK 0x5A): граната должна быть в руке
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      -- сначала углы
    cmd.camera = true           -- затем флаг: камера повернётся к ним

    if state == "pull" then     -- держим атаку: выдёргиваем чеку
        cmd.IN_ATTACK = (ticks == 0) and 3 or 1
        ticks = ticks + 1
        if ticks >= PULL_TICKS then state, ticks = "release", 0 end
    else                        -- отпускаем и ещё держим углы до вылета гранаты
        cmd.IN_ATTACK = (ticks == 0) and 2 or 0
        ticks = ticks + 1
        if ticks >= HOLD_TICKS then state = "idle" end
    end
end)

cmd:buttons()#

Три маски кнопок команды.

Возвращает: 64-битные целые value, changed, scroll — зажатые, изменившиеся, прокрутка.

events.pre_movement:set(function(cmd)
    local value, changed = cmd:buttons()
    if value ~= 0 then
        -- зажата хотя бы одна кнопка
    end
end)

cmd:new()#

Копия команды. Запись в копию на игру не влияет.

Возвращает: cmd.

events.pre_movement:set(function(cmd)
    local copy = cmd:new()
    copy.forwardmove = 0          -- игра этого не увидит
    print(cmd.forwardmove)        -- исходное значение
end)

cmd:finalize()#

Завершает подтики команды на месте.

Возвращает: ничего.

events.createmove:set(function(cmd)
    cmd:finalize()
end)

cmd:finalized()#

Копия команды с завершёнными подтиками. Исходная команда не меняется.

Возвращает: cmd.

events.pre_movement:set(function(cmd)
    local fin = cmd:finalized()
    print(fin.forwardmove)
end)