Основная цель

Основная цель этой статьи, показать, как же хорош новый патч и почему не стоит сидеть ну ГУИ или же 126 патче
Последние патчи дают доступ к такому функционалу, который многие бы посчитали неестественным
а именно тот самый доступ к курсору, за которым я так давно гоняюсь

Старые способы

Сильно не хочу расписывать, но на 126 патче, доступ к курсору можно было получить только через мемхак . И то на синхронизацию положения через игровой кеш нужно было бы затратить 2 секунды
олдовый код
gamecache cache = InitGameCache("cache")
function SyncReal takes player p, real val returns real
if (GetLocalPlayer() == p) then
 StoreReal(cache, "", "", val)
endif
TriggerSyncStart()
if (GetLocalPlayer() == p) then
SyncStoredReal(cache, "", "")
endif
TriggerSleepAction(2)// меньшнее значение вызывает десинх
TriggerSyncReady()
return GetStoredReal(cache, "", "")
endfunction
//==================================================
function Trig_CameraSynh_Actions takes nothing returns nothing
player p = Player(0)
real x=0
real y=0
real syncx=0
real syncy=0
string xs,ys
if GetLocalPlayer()==p
xs=R2S(GetMouseTerrainX())
ys=R2S(GetMouseTerrainY())
x=S2R(xs)// перезапись через строковый тип
y=S2R(ys)// иначе нули
endif
syncx = SyncReal(p, x)
syncy = SyncReal(p, y)
CreateUnit(p, 'e009', syncx, syncy, 0)
endfunction

//===========================================================================
function InitTrig_CameraSynh takes nothing returns nothing
    set gg_trg_CameraSynh = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_CameraSynh, 2.10 )
    call TriggerAddAction( gg_trg_CameraSynh, function Trig_CameraSynh_Actions )
endfunction
И это было ужасно, так же мною был найден способ следить за курсором через автоповтор ПКМ (RMB), с помощью системы WFE , такая комбинация позволяла получать курсор другого игрока при зажатой ПКМ вот в этом проекте , но частота повтора больше чем 0,1 вызывала большие нагрузки по сети при синхронизации пакетов

А зачем же вообще нужен курсор

Да для чего угодно, например для того чтобы:
  1. Рисовать в варкрафте как в Paint
  2. Делашть шутеры
  3. Делать интересные системы, требущие направления при касте (вспоминаем скил Пангольера или стенку Дарксира из Доты 2)
  4. Делать системы квиккастов, как вот в такой карте
  5. Рисовать заклинания как в серии игры Trine
  6. И самое главное, зачем мы все сегодня собрались это:
Делать так, чтобы башня вращалась вслед за курсором

А что же теперь

А теперь это всё может заменить на 2 ГУИ триггера (почти), если бы ГУИ был нормальным, то может быть и да, а так, там есть 1 нюанас
нюанс
На ГУИ нельзя повернуть башню, которая находится на кости turret, на ГУИ можно указать только голову head и туловище chest
но это легко обойти, если переименовать кость в редакторе MDLVIS
Триггер 1: двигаем указатель вслед за курсором
Триггер 2: закрепляем кость танка за подвижным указателем
как раз таки кости turret и нет на скрине

А на Lua вот

так вот
(Отредактировано Назаром, я бы так не смог)
do
    local tankId           = FourCC('hmtt') -- ID боевой машины, башней которой планируете крутить
    local pointerId        = FourCC('ewsp') -- ID  невидимого указателя, который будет следовать за курсором
    local tank             = {} -- массив боевых машин
    local pointer          = {} -- массив указателей
    local InitGlobalOrigin = InitGlobals
    function InitGlobals()
        InitGlobalOrigin()
        -- регистрация триггера с событием, "Мышь передвинута"
        local mouseMoveTrigger = CreateTrigger()
        -- смешение юнита указателя к курсору
        TriggerAddAction(mouseMoveTrigger, function()
            local id = GetPlayerId(GetTriggerPlayer())
            SetUnitX(pointer[id], BlzGetTriggerPlayerMouseX())
            SetUnitY(pointer[id], BlzGetTriggerPlayerMouseY())
        end)
        --
        for i = 0, bj_MAX_PLAYER_SLOTS - 1 do
            local player = Player(i)
            if GetPlayerSlotState(player) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(player) == MAP_CONTROL_USER then
                TriggerRegisterPlayerEvent(mouseMoveTrigger, player, EVENT_PLAYER_MOUSE_MOVE)
                tank[i]    = CreateUnit(player, tankId, GetPlayerStartLocationX(player), GetPlayerStartLocationY(player), 0)
                pointer[i] = CreateUnit(player, pointerId, 0, 0, 0)
                SetUnitLookAt(tank[i], 'bone_turret', pointer[i], 0, 0, 90)
            end
        end
    end
end
В принципе даже настройки выведены, надо указать лишь кто танк, а кто указатель, и в качестве указателя лучше использовать правильно настроенного Dummy (Неуязвимого москита, без тени и модели, и без обзора)
Как всегда видео образец и карта пример
(Обязательно приму замечания гуру луа и справлюсь, если что не так)
Hive
В качестве подопытной, используется эта модель
Только у неё удалены анимации Stand -2, Stand -3, Walk-2, Walk-3
В которых башня вращается сама по себе
`
ОЖИДАНИЕ РЕКЛАМЫ...
22
Теперь сделай так чтобы дамми не перемешал а двигал к следом позиции со скоростью 2000. Это даст плавный поворот при 180 градусов. Ну много фич можеш замутить.
33
pro100master, да согласен, сейчас башня двигается рвано, зато мнгновенно, может это и лучше в игровом плане, потому что нет задержки при поворотах, хотя выглядит не очень
11
Осталось дождаться, когда дадут возможность проигрывать анимацию отдельных частей модельки независимо и можно будет делать выстрел или атаку в движении. Ото пока это тоже костылеписание с разделением модели на две части (хотя я и такой наработки не встречал)
30
Что если не использовать даммика, а заставить юнита смотреть на себя и манипулировать offset?
---@param whichUnit unit
---@param whichBone string
---@param lookAtTarget unit
---@param offsetX real
---@param offsetY real
---@param offsetZ real
function SetUnitLookAt(whichUnit, whichBone, lookAtTarget, offsetX, offsetY, offsetZ) end
33
NazarPunk, я давно пробовал заставить смотреть на самого себя, но была полная ерунда, чаще всего дуло загибается просто вниз
17
@ Bergi_Bear, можете добавить проверку на 0.0, ибо когда мышь на интерфейсе либо в недоступной зоне, то отправляются нули
на 7й секунде видео это видно
30
можете добавить проверку на 0.0, ибо когда мышь на интерфейсе либо в недоступной зоне, то отправляются нули
на 7й секунде видео это видно
Это же демо пример, а не полноценная система. Можно ж ещё например попробовать создать одного даммика, ориентировать всех на него и с помощью матемагии манипулировать оффсетами.
33
N1ghtSiren, да на интерфейсе, на черных запрпедельных областях... как только начнем пилить полноценную карту на этой системе, тогда да, обязательно появится эти проверки и темка обновится
27
идея очень хорошая, возьму на вооружению (хотя что то такое и предлагал ранее)
а нельзя ли сделать без даймика, мб модель танка с вращающей пушкой (пример) сделать?
хотя если использовать даймика, что можно намутить конструктор танка (кто играл на сонька Warzone 2100 поймет): меняешь корпус или меняешь пушку. Это же классно. а вот с моделью танка наверн тяжелее?
у тебя пушка может подниматься наверх (горизонтальные наклоны нативка делает)? стрельба по возвышенным противникам или артиллерия
30
а нельзя ли сделать без даймика, мб модель танка сделать?
Можно поэксперементировать с направлением на себя или одним даммиком на всех.
30
как это на себя?
В SetUnitLookAt указать целью самого юнита.
27
хотя если использовать даймика, что можно намутить конструктор танка (кто играл на сонька Warzone 2100 поймет): меняешь корпус или меняешь пушку. Это же классно. а вот с моделью танка наверн тяжелее?
неправильно подумал. я думал там два юнита: сам корпус и перемещающая за корпусом пушка. а там значит целиком один юнит


еще помню констр-страйк в варкрафте от первого лица, мб делать снайперские выстрелы из танка
21
Ты смотри аккуратнее, там модель Генерала Франка

А так система норм тема
30
Ты смотри аккуратнее, там модель Генерала Франка
И что с того? Её же не режут на запчасти и не приклеивают к своей модели.
25
На ГУИ нельзя повернуть башню, которая находится на кости turret, на ГУИ можно указать только голову head и туловище chest но это легко обойти, если переименовать кость в редакторе MDLVIS
Есть предположение, а через код можно ли указать другие кости кроме head и chest? Тогда не придется переименовывать их через mdlvis.
33
konvan5, да я имено это и сделал через код
SetUnitLookAt(tank[i], 'bone_turret', pointer[i], 0, 0, 90)
bone_turret
Чтобы оставить комментарий, пожалуйста, войдите на сайт.