Основная цель
Основная цель этой статьи, показать, как же хорош новый патч и почему не стоит сидеть ну ГУИ или же 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 вызывала большие нагрузки по сети при синхронизации пакетов
А зачем же вообще нужен курсор
Да для чего угодно, например для того чтобы:
- Рисовать в варкрафте как в Paint
- Делашть шутеры
- Делать интересные системы, требущие направления при касте (вспоминаем скил Пангольера или стенку Дарксира из Доты 2)
- Делать системы квиккастов, как вот в такой карте
- Рисовать заклинания как в серии игры Trine
- И самое главное, зачем мы все сегодня собрались это:
А что же теперь
А теперь это всё может заменить на 2 ГУИ триггера (почти), если бы ГУИ был нормальным, то может быть и да, а так, там есть 1 нюанас
нюанс
На ГУИ нельзя повернуть башню, которая находится на кости turret, на ГУИ можно указать только голову head и туловище chest
но это легко обойти, если переименовать кость в редакторе MDLVIS
но это легко обойти, если переименовать кость в редакторе 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
В которых башня вращается сама по себе
Только у неё удалены анимации Stand -2, Stand -3, Walk-2, Walk-3
В которых башня вращается сама по себе
Ред. Koladik
Ред. nazarpunk
на 7й секунде видео это видно
Ред. MpW
а нельзя ли сделать без даймика, мб модель танка с вращающей пушкой (пример) сделать?
хотя если использовать даймика, что можно намутить конструктор танка (кто играл на сонька Warzone 2100 поймет): меняешь корпус или меняешь пушку. Это же классно. а вот с моделью танка наверн тяжелее?
у тебя пушка может подниматься наверх (горизонтальные наклоны нативка делает)? стрельба по возвышенным противникам или артиллерия
Ред. MpW
Ред. nazarpunk
Есть предположение, а через код можно ли указать другие кости кроме head и chest? Тогда не придется переименовывать их через mdlvis.