я рак в задержках

whyhardlyz

Известный
Автор темы
119
88
ни одна задержка при помощи таймера GetTickCount в мейнлупе не работает, можете пальцем ткнуть в чём ошибка, или помочь расставить dwTickStart = GetTickCount();

C++:
if (state)
    {
        if ((GetTickCount() - dwTickStart) > 50)
        {
            // тут выполняется функция
            float playerPos[3] = { PEDSELF->GetPosition()->fX, PEDSELF->GetPosition()->fY, PEDSELF->GetPosition()->fZ };
            float targetPos[3] = { SF->getSAMP()->getPlayers()->pRemotePlayer[pId]->pPlayerData->inCarData.fPosition[0], SF->getSAMP()->getPlayers()->pRemotePlayer[pId]->pPlayerData->inCarData.fPosition[1], SF->getSAMP()->getPlayers()->pRemotePlayer[pId]->pPlayerData->inCarData.fPosition[2] };
            dwTickStart = GetTickCount();
            if (getDist(playerPos, targetPos) < 75.0f)
            {
                // тут выполняется функция
                dwTickStart = GetTickCount();
                if ((GetTickCount() - dwTickStart) > 1200)
                {
                    for (int i = 1; i <= 200; i++)
                    {
                        if (SF->getSAMP()->getPlayers()->IsPlayerDefined(pId))
                        {
                            float newPlayerPos[3] = { PEDSELF->GetPosition()->fX, PEDSELF->GetPosition()->fY, PEDSELF->GetPosition()->fZ };
                            float newTargetPos[3] = { SF->getSAMP()->getPlayers()->pRemotePlayer[pId]->pPlayerData->inCarData.fPosition[0], SF->getSAMP()->getPlayers()->pRemotePlayer[pId]->pPlayerData->inCarData.fPosition[1], SF->getSAMP()->getPlayers()->pRemotePlayer[pId]->pPlayerData->inCarData.fPosition[2] };
                            // тут выполняется функция
                            dwTickStart = GetTickCount();
                            if (getDist(newPlayerPos, newTargetPos) < 75.0f)
                            {
                                if ((GetTickCount() - dwTickStart) > 50)
                                {
                                    // тут выполняется функция
                                    dwTickStart = GetTickCount();
                                }
                            }
                        }
                        state = false;
                    }
                }
            }
        }
    }
 

RedHolms

Известный
Проверенный
617
360
Тогда уж делать сразу нормально.
Я делал так:
Есть функция, скажет setInterval, мы в неё передаём функцию и задержку.
Есть хук CGame::Process, он каждый кадр чекает, какие интервалы уже прошли, и вызывает их если надо

Есть такой очень старый код, может из него станет яснее:
C++:
-- НАДО ЛИНКОВАТЬ С winmm.dll
#include <timeapi.h>

unsigned long current_time() {
    return timeGetTime();
}

void LayersManager::DelayCall(unsigned long delay, std::function<void(void)> fn) {
   m_log.Debug("New delay call with target %u", current_time() + delay);
   m_delayCalls.push_back({ current_time() + delay, fn });
}

void LayersManager::_OnProcess() {
   if (m_lastSave == 0) m_lastSave = current_time();

   for (auto it = m_pressedKeys.begin(); it != m_pressedKeys.end(); ++it) {
      // if (it->frames) keybd_event(it->vkey, 0, KEYEVENTF_KEYUP, 0);
      // else ++it->frames;
      keybd_event(it->vkey, 0, KEYEVENTF_KEYUP, 0);
      // SendMessageA(sampGetWindowHandle(), WM_KEYUP, VK_SHIFT, 0);
      m_pressedKeys.erase(it); --it;
   }

   std::vector<DelayCallData> delayCallsCopy = std::vector<DelayCallData>(m_delayCalls);
   for (size_t i = 0; i < delayCallsCopy.size(); ++i) {
      auto const& it = delayCallsCopy.begin() + i;
      if (current_time() >= it->target_time) {
         m_log.Debug("Delay call %u executed", it->target_time);
         if (it->handler) it->handler();
         m_delayCalls.erase(m_delayCalls.begin() + i);
      }
   }

   if (current_time() - m_lastSave >= 30000) {
      SaveAll();
      m_lastSave = current_time();
   }

   for (auto& l : m_processLayers) l->Process();
}

Использование:
C++:
m_log.Debug("Local ping: %u", sampGetLocalPlayerPing());
      
sampSetGameKeyState(14, 8);
LayersManager::Get().DelayCall(50, []() {
    BitStream bs;
    bs.Write((short)sampGetLocalPlayerID());
    bs.Write<unsigned char>(sizeof("MISC")-1);
    bs.Write("MISC", sizeof("MISC")-1);
    bs.Write<unsigned char>(sizeof("plyr_shkhead")-1);
    bs.Write("plyr_shkhead", sizeof("plyr_shkhead")-1);
    bs.Write(4.0f);
    bs.Write(false);
    bs.Write(true);
    bs.Write(true);
    bs.Write(true);
    bs.Write<uint32_t>(1);
    sampEmulateIncomingRPC(86, &bs);

    LayersManager::Get().DelayCall(150, []() {
        sampSetGameKeyState(14, 8);
    });
});