Самый адекватный способ как по мне - это сделать не-героев т.е. эволюционирующих холопов героями, без прироста статов и без иконки героя, с оригинальными типами брони и атаки.
Тогда будет меньше возни с "просмотром" уровня героя и т.д. и т.п.
CS_H2I() заменено на GetHandleId
GetAttachedObject() и другие удалены, т.к. в коде не используется
GameCache2Trigger() переделано, сразу изменён тип переменной на gamecache, название не изменено - gg_trg_xxx (gg_trg_MultiDrain, gg_trg_Boomerang_Axes)
H2I и xxxH2I- переделано:
function H2I takes handle h returns integer
return (GetHandleId(h))
endfunction
//Функции по возвращению int в данные переделаны под ХТ по типу:
function I2X takes integer i returns XXX
call SaveFogStateHandle(udg_typecasting,0,0,ConvertFogState(i))
return (LoadXXXHandle(udg_typecasting,0,0))
endfunction
:
function I2U takes integer i returns unit
call SaveFogStateHandle(udg_typecasting,0,0,ConvertFogState(i))
return (LoadUnitHandle(udg_typecasting,0,0))
endfunction
function I2T takes integer t returns trigger
call SaveFogStateHandle(udg_typecasting,0,0,ConvertFogState(t))
return (LoadTriggerHandle(udg_typecasting,0,0))
endfunction
function I2G takes integer g returns group
call SaveFogStateHandle(udg_typecasting,0,0,ConvertFogState(g))
return (LoadGroupHandle(udg_typecasting,0,0))
endfunction
function GetAttachedUnit takes handle h,string label returns unit
local integer i = GetAttachedInt(h,label)
call SaveFogStateHandle(udg_typecasting,0,0,ConvertFogState(i))
return (LoadUnitHandle(udg_typecasting,0,0))
endfunction
function FCGetHandleUnit takes nothing returns unit
local integer i=FCGetHandleHandle(GetExpiredTimer(),"dummy")
call SaveFogStateHandle(udg_typecasting,0,0,ConvertFogState(i))
return (LoadUnitHandle(udg_typecasting,0,0))
endfunction
//(их довольно много, все не припомню)
//CycloneGetHandleHandle - переделано, теперь возвращает юнита вместо handle
function CycloneGetHandleHandle takes handle subject,string name returns unit
local integer i = GetStoredInteger(CycloneCache(),I2S(CycloneH2I(subject)),name)
call SaveFogStateHandle(udg_typecasting,0,0,ConvertFogState(i))
return (LoadUnitHandle(udg_typecasting,0,0))
endfunction
//SlowGetHandleHandle() - переделано, теперь возвращает юнита вместо handle
function SlowGetHandleHandle takes handle subject,string name returns unit
local integer i = GetStoredInteger(SlowCache(),I2S(SlowH2I(subject)),name)
call SaveFogStateHandle(udg_typecasting,0,0,ConvertFogState(i))
return (LoadUnitHandle(udg_typecasting,0,0))
endfunction
//CycloneGetHandleHandle() - переделано, теперь возвращает юнита вместо handle:
function CycloneGetHandleHandle takes handle subject,string name returns unit
local integer i = GetStoredInteger(CycloneCache(),I2S(CycloneH2I(subject)),name)
call SaveFogStateHandle(udg_typecasting,0,0,ConvertFogState(i))
return (LoadUnitHandle(udg_typecasting,0,0))
endfunction
Всё остальное как было, так и осталось.
Сохранение данных в кэш тут реализовано вот так:
раскрыть
function AttachInt takes handle h,string label,integer x returns nothing
local string k=I2S(GetHandleId(h))
if x==0 then
call FlushStoredInteger(udg_cscache,k,label)
else
call StoreInteger(udg_cscache,k,label,x)
endif
endfunction
function AttachReal takes handle h,string label,real x returns nothing
local string k=I2S(GetHandleId(h))
if x==0 then
call FlushStoredReal(udg_cscache,k,label)
else
call StoreReal(udg_cscache,k,label,x)
endif
endfunction
function AttachBoolean takes handle h,string label,boolean x returns nothing
local string k=I2S(GetHandleId(h))
if not x then
call FlushStoredBoolean(udg_cscache,k,label)
else
call StoreBoolean(udg_cscache,k,label,x)
endif
endfunction
function AttachString takes handle h,string label,string x returns nothing
local string k=I2S(GetHandleId(h))
if x==""then
call FlushStoredString(udg_cscache,k,label)
else
call StoreString(udg_cscache,k,label,x)
endif
endfunction
function AttachObject takes handle h,string label,handle x returns nothing
call AttachInt(h,label,GetHandleId(x))
endfunction
function GetAttachedInt takes handle h,string label returns integer
local integer r=udg_asetsint
local integer i
local integer L
local string c
local string num
if(r>0)then
if SubString(label,0,1)=="#"then
set udg_asetsint=r-1
set i=0
set num=""
loop
set i=i+1
set c=SubString(label,i,i+1)
exitwhen(c==";")or(c=="")
set num=num+c
endloop
if c==";"then
return GetStoredInteger(udg_cscache,I2S(GetHandleId(h))+";"+SubString(label,i+1,StringLength(label)+1),num)
endif
endif
endif
return GetStoredInteger(udg_cscache,I2S(GetHandleId(h)),label)
endfunction
function GetAttachedUnit takes handle h,string label returns unit
local integer i = GetAttachedInt(h,label)
call SaveFogStateHandle(udg_typecasting,0,0,ConvertFogState(i))
return (LoadUnitHandle(udg_typecasting,0,0))
endfunction
Знаю способ смотреть сид через реплей.
Недавно пытался переназначить его функцией во время init, но ни к чему оно не привело, сид как был рандомный так и остался.
Код или карту в студию, ну или хотябы скрин кода.
Возможно что для 4го создаётся и высвечивается отдельный диалог, в который не добавлены кнопки.
Но опять же, пальцем в небо...
В ласт патчах же добавили целую гору функций для работы со спецэффектами - можно задать масштаб, перекрасить отдельно от того к чему прикреплено, или же повернуть
УУУ, гуи, враг мой древний
Вообще можно прикрутить это всё на один таймер.
Например так:
globals
integer n = 0
endglobals
function movieOne takes nothing returns nothing
call BJDebugMsg("movieOne actions")
endfunction
function movieTwo takes nothing returns nothing
call BJDebugMsg("movieTwo actions")
endfunction
function movieThree takes nothing returns nothing
call BJDebugMsg("movieThree actions")
endfunction
function testLoop takes nothing returns nothing
local timer t
local real r
if n==0 then
set t = CreateTimer()
call movieOne()
set r = 6.0 //Длительность 1го мувика
call TimerStart(t,r,false,function testLoop)
set n = 1
//Неуверен, но может баговать из-за того что пойдёт проверка дальше и выполнится всё сразу. Да, можно поменять порядок, но return выглядит понятнее.
return
elseif n ==1 then
set t = GetExpiredTimer()
call movieTwo()
set r = 5.0 //Длительность 2го мувика
call TimerStart(t,r,false,function testLoop)
set n = 2
return
elseif n ==2 then
set t = GetExpiredTimer()
call movieThree()
set r = 5.0 //Длительность 3го мувика
call TimerStart(t,r,false,function testLoop)
set n = 3
return
elseif n ==3 then
set t = GetExpiredTimer()
call DestroyTimer(t)
elseif n >=4 or n<0 then
call BJDebugMsg("Some error happened")
endif
set t = null
endfunction
Учитесь использовать дебаг, например можете прикрутить на таймер с 0.3 вывод вашей переменной на экран. эээ кодировка, вернись
Да, моделька даммика подошла, и всё получилось как хотелось
Странно, что SetUnitAnimation не равно SetUnitAnimationByIndex, ибо я с часа полтора промаялся над первым, ибо примеров небыло под рукой :d
Покопался в поиске, по хайву, нашёл пару идей
SetUnitLookAt особо не помог, т.к.на 1й кадр идёт мерцание, а в лупе на 0.03125 и вовсе мерцает каждый второй кадр.
По поводу использования обычных абилок - это довольно сложно, ибо переделывать под обычные абилки + динамические триггеры с отловом урона - ну такое...
С лицухой поинтереснее, ибо там есть волшебная палочка в виде BlzSetEventDamage...
Нашёл модельку даммика с анимациями поворота, но пока не разобрался как с ней работать
В крайнем случае просто забью на это :D
Попробуйте вот это. Видимо обрезан код, странно слишком 2 exitwhen видеть
раскрыть
unit EnemyInGroup (unit u, float x, float y, float range) {
group enemies = CreateGroup()
unit u_e
boolean B = false
unit u
GroupEnumUnitsInRange(enemies, x, y, range, Condition(function SimpleCond))
loop
exitwhen (B==true)
u_e = FirstOfGroup(enemies)
if IsUnitEnemy(u_e, GetOwningPlayer(u)) then
B = true
u = u_e
else
GroupRemoveUnit(enemies, u_e)
endif
endloop
DestroyGroup(enemies)
enemies = null
u_e = null
if (B == false) then //Если врагов в группе нет, обнуляем юнита и возвращаем null
u = null
return null
else // Если есть, то возвращаем первого юнита
return u
}
>>Пишет missing return, хотя он есть, чо делать?
return обозначает выход из функции, должен стоять в самом её конце, ибо тот код, что ниже, будет unreachable code => никогда не выполнится
У меня сделано через структуры +таймеры.
На таймер крепятся все бафы/дебафы, когда он истекает = статы пропадают
Отдельная ХТ под всю эту систему, пока хз, как будет проседать под сильной нагрузкой
На хендл юнита крепятся таймеры (в свободные ячейки(пока всего лишь 30))
Каждый новый баф кидается в новую ячейку, и потом лупом перебираются те, что ещё есть.
Скрины:
Правда с таким способом, вам наверно придётся переделывать всё под один шаблон...
if GetPlayerController(ConvertedPlayer(udg_pid)) != MAP_CONTROL_COMPUTER then
endif
if GetPlayerSlotState(ConvertedPlayer(udg_pid)) != PLAYER_SLOT_STATE_EMPTY then
endif
if GetPlayerSlotState(ConvertedPlayer(udg_pid)) != PLAYER_SLOT_STATE_LEFT then
endif
» WarCraft 3 / Проблема с анимациями
» WarCraft 3 / Опыт для любого юнита (не героя)
Тогда будет меньше возни с "просмотром" уровня героя и т.д. и т.п.
» WarCraft 3 / MooMoo 1.5 Reborn
Все изменения:
Сохранение данных в кэш тут реализовано вот так:
» WarCraft 3 / Мапа не запускается.
» WarCraft 3 / Мапа не запускается.
» WarCraft 3 / Неслучайный рандом
Сколько раз прокрутится до того как упадёт - вот вам и сид
» WarCraft 3 / Неслучайный рандом
Недавно пытался переназначить его функцией во время init, но ни к чему оно не привело, сид как был рандомный так и остался.
» WarCraft 3 / Jass времён 1.24
» WarCraft 3 / Ошибка в диалогах
Возможно что для 4го создаётся и высвечивается отдельный диалог, в который не добавлены кнопки.
Но опять же, пальцем в небо...
» WarCraft 3 / Синхронизация.
Ред. N1ghtSiren
» WarCraft 3 / Проверка способности
Атакующий юнит имеет нашу абилку - яд
Снизить атакуемому юниту броню на Х
» WarCraft 3 / Статы, дополняющие урон
» WarCraft 3 / Статы, дополняющие урон
Ред. N1ghtSiren
» WarCraft 3 / Увеличение значения целочисленной переменной на 1
Вообще можно прикрутить это всё на один таймер.
эээ кодировка, вернись
» WarCraft 3 / Просадка fps при записи локалок в глобалки
Ну и приложите полный код.
Мб у вас в этот момент идёт прелоад и из-за этого фпс проседает
» WarCraft 3 / Поворот даммика
Странно, что SetUnitAnimation не равно SetUnitAnimationByIndex, ибо я с часа полтора промаялся над первым, ибо примеров небыло под рукой :d
» WarCraft 3 / Поворот даммика
SetUnitLookAt особо не помог, т.к.на 1й кадр идёт мерцание, а в лупе на 0.03125 и вовсе мерцает каждый второй кадр.
С лицухой поинтереснее, ибо там есть волшебная палочка в виде BlzSetEventDamage...
Нашёл модельку даммика с анимациями поворота, но пока не разобрался как с ней работать
В крайнем случае просто забью на это :D
» XGM Конкурсы / Warcraft III Mini-Game Contest-2018
» WarCraft 3 / TerrainId
в редакторе Глушь = Outland
» WarCraft 3 / Изменение Loadscreen
Ред. N1ghtSiren
» WarCraft 3 / missing return
Ред. N1ghtSiren
» WarCraft 3 / [Загадка] Пробел при позиции игрока!
» WarCraft 3 / Аттач группы триггеров
На таймер крепятся все бафы/дебафы, когда он истекает = статы пропадают
Отдельная ХТ под всю эту систему, пока хз, как будет проседать под сильной нагрузкой
На хендл юнита крепятся таймеры (в свободные ячейки(пока всего лишь 30))
Каждый новый баф кидается в новую ячейку, и потом лупом перебираются те, что ещё есть.
Скрины:
» WarCraft 3 / Выбор всех реальных игроков.