Алгоритмы, Наработки и Способности
Способ реализации:
Jass
Тип:
Наработка
**1. Требуется редактор jngp(который может работать с мемхаком), либо jasscraft, либо иной способ, чтобы наработки с мемхаком корректно компились
  1. Сломанный массив Memory (который позволяет читать и писать в память)**
  2. Зачем это нужно ? для смены параметров скила (кд, дальность применения, и других данных), для определенного скила, который имеется у конкретного юнита
Собственно код.
function SetAbilityDataAInteger takes integer add,integer lvl,integer newdata returns nothing
    if Memory[add/4+0x54/4]>0 then
        set Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4 + (lvl-1)*26 + 8 ] = newdata
    endif
endfunction
function GetAbilityDataAInteger takes integer add,integer lvl  returns integer
    if Memory[add/4+0x54/4]>0 then
        return Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4 + (lvl-1)*26 + 8 ] 
    endif
    return 0
endfunction

function SetAbilityDataBInteger takes integer add,integer lvl,integer newdata returns nothing
    if Memory[add/4+0x54/4]>0 then
        set Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4  + (lvl-1)*26 + 9] = newdata
    endif
endfunction
function GetAbilityDataBInteger takes integer add,integer lvl returns integer
    if Memory[add/4+0x54/4]>0 then
      return Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4  + (lvl-1)*26 + 9]
    endif
    return 0
endfunction

function SetAbilityDataCInteger takes integer add,integer lvl,integer newdata returns nothing
    if Memory[add/4+0x54/4]>0 then
        set Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4 + (lvl-1)*26 + 10 ] = newdata
    endif
endfunction
function GetAbilityDataCInteger takes integer add,integer lvl returns integer
    if Memory[add/4+0x54/4]>0 then
        return Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4 + (lvl-1)*26 + 10 ]
    endif
    return 0
endfunction

function SetAbilityDataDInteger takes integer add,integer lvl,integer newdata returns nothing
    if Memory[add/4+0x54/4]>0 then
        set Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4  + (lvl-1)*26 + 11 ] = newdata
    endif
endfunction
function GetAbilityDataDInteger takes integer add,integer lvl returns integer
    if Memory[add/4+0x54/4]>0 then
        return Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4  + (lvl-1)*26 + 11 ]
    endif
    return 0
endfunction

function SetAbilityDataEInteger takes integer add,integer lvl,integer newdata returns nothing
    if Memory[add/4+0x54/4]>0 then
        set Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4 + (lvl-1)*26 + 12 ] = newdata
    endif
endfunction

function GetAbilityDataEInteger takes integer add,integer lvl,integer newdata returns integer
    if Memory[add/4+0x54/4]>0 then
        return Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4 + (lvl-1)*26 + 12 ]
    endif
    return 0
endfunction

function SetAbilityDataAReal takes integer add,integer lvl,real newdata returns nothing
    if Memory[add/4+0x54/4]>0 then
        set Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4 + (lvl-1)*26 + 8 ] = cleanInt(realToIndex(newdata))
    endif
endfunction
function GetAbilityDataAReal takes integer add,integer lvl returns real
    if Memory[add/4+0x54/4]>0 then
        return cleanReal(indexToReal( Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4  + (lvl-1)*26 + 8] ))
    endif
    return .0
endfunction

function SetAbilityDataBReal takes integer add,integer lvl,real newdata returns nothing
    if Memory[add/4+0x54/4]>0 then
        set Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4  + (lvl-1)*26 + 9] = cleanInt(realToIndex(newdata))
    endif
endfunction
function GetAbilityDataBReal takes integer add,integer lvl returns real
    if Memory[add/4+0x54/4]>0 then
        return cleanReal(indexToReal( Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4  + (lvl-1)*26 + 9] ))
    endif
    return .0
endfunction

function SetAbilityDataCReal takes integer add,integer lvl,real newdata returns nothing
    if Memory[add/4+0x54/4]>0 then
        set Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4 + (lvl-1)*26 + 10 ] = cleanInt(realToIndex(newdata))
    endif
endfunction
function GetAbilityDataCReal takes integer add,integer lvl returns real
    if Memory[add/4+0x54/4]>0 then
        return cleanReal(indexToReal( Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4  + (lvl-1)*26 + 10] ))
    endif
    return .0
endfunction

function SetAbilityDataDReal takes integer add,integer lvl,real newdata returns nothing
    if Memory[add/4+0x54/4]>0 then
        set Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4  + (lvl-1)*26 + 11 ] = cleanInt(realToIndex(newdata))
    endif
endfunction
function GetAbilityDataDReal takes integer add,integer lvl returns real
    if Memory[add/4+0x54/4]>0 then
        return cleanReal(indexToReal( Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4  + (lvl-1)*26 + 11] ))
    endif
    return .0
endfunction

function SetAbilityDataEReal takes integer add,integer lvl,real newdata returns nothing
    if Memory[add/4+0x54/4]>0 then
        set Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4 + (lvl-1)*26 + 12 ] = cleanInt(realToIndex(newdata))
    endif
endfunction
function GetAbilityDataEReal takes integer add,integer lvl returns real
    if Memory[add/4+0x54/4]>0 then
        return cleanReal(indexToReal( Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4  + (lvl-1)*26 + 12] ))
    endif
    return .0
endfunction

function SetAbilityDataCast takes integer add,integer lvl,real newdata returns nothing
    if Memory[add/4+0x54/4]>0 then
        set Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4  + (lvl-1)*26 + 1 ] = cleanInt(realToIndex(newdata))
    endif
endfunction

function GetAbilityDataCast takes integer add,integer lvl returns real
    if Memory[add/4+0x54/4]>0 then
        return cleanReal(indexToReal(Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4  + (lvl-1)*26 + 1 ] ))
    endif
    return .0
endfunction

function SetAbilityDataDur takes integer add,integer lvl,real newdata returns nothing
    if Memory[add/4+0x54/4]>0 then
        set Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4  + (lvl-1)*26 + 2 ] = cleanInt(realToIndex(newdata))
    endif
endfunction


function GetAbilityDataDur takes integer add,integer lvl returns real
    if Memory[add/4+0x54/4]>0 then
        return cleanReal(indexToReal(Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4  + (lvl-1)*26 +2] ))
    endif
    return .0
endfunction

function SetAbilityDataHeroDur takes integer add,integer lvl,real newdata returns nothing
    if Memory[add/4+0x54/4]>0 then
        set Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4  + (lvl-1)*26 + 3 ] = cleanInt(realToIndex(newdata))
    endif
endfunction
function GetAbilityDataHeroDur takes integer add,integer lvl returns real
    if Memory[add/4+0x54/4]>0 then
        return cleanReal(indexToReal(Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4  + (lvl-1)*26 +3] ))
    endif
    return .0
endfunction

function SetAbilityDataCooldown takes integer add,integer lvl,real newdata returns nothing
    if Memory[add/4+0x54/4]>0 then
        set Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4 + (lvl-1)*26 + 5 ] = cleanInt(realToIndex(newdata))
    endif
endfunction
function GetAbilityDataCooldown takes integer add,integer lvl returns real
    if Memory[add/4+0x54/4]>0 then
        return cleanReal(indexToReal(Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4  + (lvl-1)*26 +5] ))
    endif
    return .0
endfunction

function SetAbilityDataHeroArea takes integer add,integer lvl,real newdata returns nothing
    if Memory[add/4+0x54/4]>0 then
        set Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4  + (lvl-1)*26 + 6 ] = cleanInt(realToIndex(newdata))
    endif
endfunction
function GetAbilityDataHeroArea takes integer add,integer lvl returns real
    if Memory[add/4+0x54/4]>0 then
        return cleanReal(indexToReal(Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4  + (lvl-1)*26 +6] ))
    endif
    return .0
endfunction

function SetAbilityDataHeroRng takes integer add,integer lvl,real newdata returns nothing
    if Memory[add/4+0x54/4]>0 then
        set Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4  + (lvl-1)*26 + 7 ] = cleanInt(realToIndex(newdata))
    endif
endfunction
function GetAbilityDataHeroRng takes integer add,integer lvl returns real
    if Memory[add/4+0x54/4]>0 then
        return cleanReal(indexToReal(Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4  + (lvl-1)*26 +7] ))
    endif
    return .0
endfunction

function SetAbilityManaCostAddr2 takes integer add,integer lvl,integer mc returns nothing
    if Memory[add/4+0x54/4]>0 then
        set Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4  +(lvl-1)*26 + 4 ] = mc
    endif
endfunction
function GetAbilityManaCostAddr2 takes integer add,integer lvl returns integer
    if Memory[add/4+0x54/4]>0 then
        return Memory[ Memory[Memory[add/4+0x54/4]/4+0x54/4]/4 + (lvl-1)*26 ]
    endif
    return 0
endfunction
function GetAbilityMaxLevel2 takes integer abil returns integer 
    return Memory[Memory[abil/4+0x54/4]/4+15]
endfunction


//Вспомогательные функции
function GetAbilityTableId takes integer a returns integer
    return Memory[Memory[a/4+0x54/4]/4+0x54/4]
endfunction
function SetAbilityTableId takes integer a,integer TableId returns nothing
    set Memory[Memory[a/4+0x54/4]/4+0x54/4] = TableId
endfunction
function GetAbilityDataId takes integer a returns integer 
    return Memory[a/4+0x54/4]
endfunction
function SetAbilityDataId takes integer a, integer DataId returns nothing 
    set Memory[a/4+0x54/4] = DataId
endfunction
// Копирование данных о скиле, и присвоению абилити новых данных.
function CloneAbilityData takes integer a returns nothing 
local integer Address = malloc(23*4)
local integer AddressTabl = malloc(22*4+26*4*GetAbilityMaxLevel2(a) + 4 )
call CopyMemory(Address,GetAbilityDataId(a),22*4)
call CopyMemory(AddressTabl,GetAbilityTableId(a),26*4*GetAbilityMaxLevel2(a) + 4)
call SetAbilityTableId(a,AddressTabl)
call SetAbilityDataId(a,Address)
endfunction
чтобы можно было менять данные, нужно использовать функцию: function CloneAbilityData takes integer a returns nothing
для конкретного скила у конкретного юнита. после применения этой функции, можно модифицировать скил, рекомендовано, часто не использовать эту функцию.
Пример:
local integer a = GetUnitAbility(u,'A001')
call CloneAbilityData(a)
call SetAbilityDataHeroRng(a,1,5000)
call SetAbilityDataBReal(a,1,450)
0
16
7 лет назад
0
у меня такого функционала не реализовано за ненадобностью, велосипед есть только у автора
0
21
7 лет назад
0
А автора месяц как нет. С велосипеда упал, наверное. =/
0
16
7 лет назад
0
ну ты можешь напрямую со скиллом работать, не клонируя его, тогда он изменится у всех юнитов, кто с ним будет бегать. вопрос в том, ЧТО ты хочешь сделать. без клона вполне жить можно, я, например, меняю каст ренж только в моент приказа и до самого каста, в остальное время - сбрасываю на дефолт
0
21
7 лет назад
0
DracoL1ch, "не клонируя его, тогда он изменится у всех юнитов" - ну то есть как GetAbilityCD и SetAbilityCD из основного мемхака вешают изменение перезарядок на абилу, а не на юнита с ней.
Так в принципе вполне подойдет, только описания изменить ну и при вешании на "дагоны" всякие предметные, конечно, в обоюдоострые мечи превращается, но нормально. А на геройские абилы сохранит мощность, если, конечно, не -duplicate играется.

Если есть такая готовая функция, очень хотелось бы.
Потому что вышенаписанные SetAbilityDataHeroRng и GetAbilityDataHeroRng без предварительного использования CloneAbilityData (опять же как помню и вижу по сообщениям выше, сейчас уже перепроверять трудно, героя в отдельной карте просто не существует) просто не давали запустить карту.
0
16
7 лет назад
0
с описаниями проблема. Почему-то редактирование строк может привести к спонтанным фаталам, и я не могу понять, в чем проблема. Даже создавая новые, игра будто кэширует длину старой, и в случае чего это может вылиться в вылет. Так что пока динамические описания я не использую, только по крайней необходимости.
изменение перезарядки ты можешь применять таймером через 0 после spell_effect, вручную регулируя конкретное время, нет нужды для этого данные менять, если не хочешь глобального эффекта
0
21
7 лет назад
0
DracoL1ch, что-то мы вообще уже кто в лес, кто по дрова, хз, я не меняю сейчас описания и у меня нет вопросов по перезарядкам.
Меня интересует функция изменения дальности спелла, не требующая для своего действия клонабилити. Что нужно, чтобы ее увидеть?
0
16
7 лет назад
0
дальность каста?
integer a=GetUnitAbility(u,id)
integer offset
integer lvl
if a>0 then
 set offset=RMem(a+0x54)
 set lvl=RMem(a+0x50)
 WMem(offset+0x74+0x68*lvl,SetRealIntoMemory(range))
endif
где RMem = readmemory, WMem = write
адреса НЕ деленные на 4, можешь сам разделить, если нужно
дальность лежит в offset+0x74+0x68*lvl и это real, поэтому нужно конвертить туда-сюда, если нужно складывать или что-то еще
0
21
7 лет назад
0
Спасибо, это, ятп, возвращает рендж абилки, а заменить как?
0
16
7 лет назад
0
WMem(offset+0x74+0x68*lvl,SetRealIntoMemory(range))
range = желаемывй ренж
0
21
7 лет назад
Отредактирован ClotPh
0
Короче, по-моему, бред какой-то, вот что вышло с налёту
Мне кажется, НЕ должно действовать, но уж на уровне текущего понимания
/
function SetSpellRange takes ability u integer r returns integer
local integer a=GetUnitAbility(u,id)
local integer offset = 0
local integer lvl = 0
if a>0 then
set offset=RMem(a+0x54)
set lvl=RMem(a+0x50)
WMem(offset+0x74+0x68*lvl,SetRealIntoMemory(r))
endif
return r
endfunction
function GetSpellRange takes ability u returns integer
local integer a=GetUnitAbility(u,id)
local integer offset = 0
local integer lvl = 0
local integer r = 0
if a>0 then
set offset=RMem(a+0x54)
set lvl=RMem(a+0x50)
set r = RMem(offset+0x74+0x68*lvl)
endif
return r
endfunction
А вообще это ппц. Автор с велосипедом уехал хрен знает куда и приходится собирать из досок самокат. Вот что значит НЕоплачиваемые помощники.
0
16
7 лет назад
0
дак всё верно, в чем бред=-то
0
21
7 лет назад
Отредактирован ClotPh
0
Ну были же ошибки.
Нде. Пока так: абила действует, но вместо неограниченного ренджа делает его ренджем вплотную. Очевидно, почему-то записывается 0 или что-то вроде
function SetSpellRange takes integer a, integer lvl, integer r returns nothing
local integer offset = 0
if a>0 then
set offset=ReadMemory(a+0x54)
set Memory[a/4+0x54/4] = r
endif
endfunction
function GetSpellRange takes integer a, integer lvl returns integer
local integer offset = 0
local integer r = 0
if a>0 then
set offset=ReadMemory(a+0x54)
set r = ReadMemory(offset+0x74+0x68*lvl)
endif
return r
endfunction
////
ДЕЛАЕМ НЕОГРАНИЧЕННУЮ ДАЛЬНОСТЬ СПОСОБНОСТИ, ЕСЛИ ОНА УЖЕ НЕ НЕОГРАНИЧЕННАЯ
if (u6 != null) and UnitHasBuffBJ(u5,'B0H6') == true then
loop
exitwhen i > 10
set i = i+1
if GetSpellRange(a, i) < 99999 then
call SetSpellRange(a,i,99999)
call UnitRemoveAbilityBJ( 'A27A', u5 )
call UnitRemoveBuffBJ( 'B0H6', u5 )
endif
endloop
endif
ДЕЛАЕМ НЕОГРАНИЧЕННУЮ ДАЛЬНОСТЬ СПОСОБНОСТИ, ЕСЛИ ОНА УЖЕ НЕ НЕОГРАНИЧЕННАЯ - ЗАКРЫТО.
////////
////////
/////////
Млять, очевидно, проблема в строчке записи, но че делать...
set Memory[a/4+0x54/4]=SetRealIntoMemory(I2R(r)) фаталит при вызове
WMem(offset+0x74+0x68*lvl,SetRealIntoMemory(I2R(r))) не компилится
write(offset+0x74+0x68*lvl,SetRealIntoMemory(I2R(r))) не компилится
//////////////////
/////////////////
function SetSpellRange takes integer a, integer lvl, real r returns nothing
local integer offset = 0
if a>0 then
set offset=ReadMemory(a+0x54)
set Memory[a/4+0x54/4]=SetRealIntoMemory(r)
endif
endfunction
Напрямую через реалку все равно так фаталит, С**А, как записать этот гребаный рендж 99999
///////////
Так, если вот тут поменять call SetSpellRange(a,i,99999) число 99999 на -99999, то фатал.
Значит, принимать число оно принимает...
///////
Какой-то капитальный бред! Меняю 99999 на 9999 - убираю одну девятку - фатал!
0
16
7 лет назад
0
ренж - это real
конвертируй правильно
0
21
7 лет назад
0
Да уже делалось так!!! НИ хрена не помогает!!!
function SetSpellRange takes integer a, integer lvl, real r returns nothing
local integer offset = 0
if a>0 then
set offset=ReadMemory(a+0x54)
set Memory[a/4+0x54/4]=SetRealIntoMemory(r)
endif
endfunction
/////////
Тут главный бред, что когда я пытаюсь вместо 99999 прописать ЛЮБОЕ число, СРАЗУ получаются фаталы. Ну что это за чушь?!? А с 99999 получается нулевой рендж.
////////////
Опять вспоминаю про деревья корнями кверху.

И сразу готовую функцию офк хрен кто даст. Вот что значит НЕоплачиваемые помощники.
/////////////////
Мля, может, так ща попробовать
function SetSpellRange takes integer a, integer lvl, integer r returns nothing
local integer offset = 0
if a>0 then
set offset=ReadMemory(a+0x54)
set Memory[offset+0x74+0x68*lvl] = r
endif
endfunction

^ предыдущее = фатал, ща там попробую I2R(r)
///////////
//////////////
Благополучно не компилится
////////
///////
Ну бред, с**а, а время летит...
////////////
//////
///////////
/////////
function SetSpellRange takes integer a, integer lvl, real r returns nothing
local integer offset = 0
if a>0 then
set offset=ReadMemory(a+0x54)
set Memory[offset+0x74+0x68*lvl] = r
endif
endfunction
И так не компилится! Хочет по адресу integer писать!!!
//////////
////////////
function SetSpellRange takes integer a, integer lvl, real r returns nothing
local integer offset = 0
if a>0 then
set offset=ReadMemory(a+0x54)
set Memory[a/4+0x54/4]=SetRealIntoMemory(r)
endif
endfunction
Закомпилировалось, чую, ща сфаталит.
/////////////////
/////////////////////
//////////////////
Сфаталило.
/////////
///////////
Попробую так подсократить пока.
function SetSpellRange takes integer a, integer lvl, integer r returns nothing
local integer offset =ReadMemory(a+0x54)
set Memory[offset+0x74+0x68*lvl] = r
endfunction
/////////////
/////////////
Ну и сразу сфаталило, ппц.
////////
///////////
function SetSpellRange takes integer a, integer lvl, integer r returns nothing
local integer offset = 0
if a>0 then
set offset=ReadMemory(a+0x54)
set Memory[offset+0x74+0x68*lvl] = r
endif
endfunction
Мля, ну ведь так оно что-то пишет. Почему оно пишет 0? Оно просто НЕ хочет писать реалку.
///////// А, нет, тьфу, так оно вообще фаталит! Вообще уже мозги болят...
function SetSpellRange takes integer a, integer lvl, integer r returns nothing
local integer offset = 0
if a>0 then
set offset=ReadMemory(a+0x54)
set Memory[a/4+0x54/4] = r
endif
endfunction
Вот так пишет 0
//////////
А вот так фаталит, что через R2I(r), что просто через r
/////////
function SetSpellRange takes integer a, integer lvl, integer r returns nothing
local integer offset = 0
if a>0 then
set offset=ReadMemory(a+0x54)
set Memory[offset+0x74+0x68*lvl] = R2I(r)
endif
endfunction
////////
////////////
Достало, только нервотрепка, походу, придется забить...
4
16
7 лет назад
4
ты вообще не понимаешь, что делаешь. неудивительно, что всё бесит.
function SetSpellRange takes integer a, integer lvl, real r returns nothing
local integer offset = 0
if a>0 then
	set offset=ReadMemory(a+0x54)
	call WriteMemory(offset+0x74+0x68*lvl,SetRealIntoMemory(r))
endif
endfunction
ты не понял, что реал и интегер - это совершенно разные числа в памяти и используешь I2R, х\отя речь шла о конвертации в памяи, ведь именно в ней ты и работаешь
ты мешаешь "чистые" и "грязные" офсеты - массив Memory[] работает ТОЛЬКО с деленнвыми на 4, Read/WriteMemory - глянь в функции, если нет деления - то тоже надо отправлять туда уже деленные. Если же в последниз есть деление, то моя функция верна.
Ну и от лвл надо отнимать 1, ибо уровни начинаются с 0, а не с 1.
0
21
7 лет назад
Отредактирован ClotPh
0
^ Компилится, но рендж не изменяется, хоть с добавлением вначале set lvl = lvl - 1, хоть без него
Функция WriteMemory из либы? Вот
function WriteMemory takes integer address, integer value returns nothing
set Memory[address / 4] = value Inline - friendly
endfunction
Т. е., ятп, деление есть.
/////////////
////////////
Попытка заменить в функции r на число - рендж не меняется.
0
16
7 лет назад
0
что в a передаешь? и вообще, чит енжин подрубай и смотри, меняется ли значение и где
0
21
7 лет назад
Отредактирован ClotPh
0
Ну как что?! То же, что и для функции Алекса: local integer a = GetUnitAbility(u5,GetSpellAbilityId())
Я ведь ее пытаюсь заменить. Функция Алекса нормально действовала, но фаталила вар после игры.
/////////////////
ППЦ. ДУРДОМ.
Короче, после удаления в старой карте строчки со CloneAbility функции Алекса внезапно сохранили работоспособность (т. е. "проблема с malloc исчезла", а что на абилу будет вешаться глобально, меня это устраивает).
Полная уверенность, что раньше так не было... Видать, помолился здесь кто за меня, ну спасибо ему навеки.
В общем, пока сворачиваюсь, изучим последствия.
///////////
////////////////
Так. Ну вроде всё зшбс. Фатала нет.
Не использую клонабилити из шапки.
Просто впрямую использую call SetAbilityDataHeroRng и call GetAbilityDataHeroRng . Это чем-то грозит?
Что изменение ренджа теперь вешается на абилку в целом, а не на конкретную у конкретного юнита - понятно, но меня это устраивает.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.