Алгоритмы, Наработки и Способности
Способ реализации:
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
ClotPh:
у тебя clone идет в цикле, создавая кучу мусора. достань его из цикла для начала.
раз у автора работает, то проблема в твоем написании где-то
2
21
7 лет назад
2
Ну код станет оптимальнее, ок, но не в этом же дело сейчас.
Все-таки мне кажется, что это из-за виджетайзера. Потому что он мне так уже уничтожал москитных даммиков, считая их "неиспользуемыми объектами", а мне потом разбираться, почему вместо файерболлов пустота летала.
Он, наверное, что-то там корежит в данных способностей при сжатии.
Потому что коды ведь одинаковые в тест-карте и в основной? (Если нет - пальцем на различия). А в тест-карте не фаталит, а в основной фаталит. А основная отличается:
  • Тем, что в ней дохрена всего;
  • Тем, что сжималась виджетайзером и оптимайзером.
Влияет ли первая причина? Вряд ли. Вывод...
***
Нде. Чушь какая-то. Дошло сейчас прогнать тест-карту через виджик и оптимайзер (т. е. протестировать так же, как основную) - нет фатала.
Оптимизация одинаковая. Код спелла одинаковый.
Одна карта фаталит вар после выхода из него, если спелл юзается, другая нет. Втф?
А что вообще будет, кстати, если клонабилити не писать?
Функция не подействует, код не скомпилируется или?...
замечание от GF RaiseD: 1.4 (злоупотребление форматированием) Существуют каты, блоки кода и форматирование.
0
16
7 лет назад
0
ClotPh:
Ну код станет оптимальнее, ок, но не в этом же дело сейчас.
?? ты вызываешь аллокацию сотен абилок, забивая память мусором. ты очень быстро израсходуешь лимит и упрешься в несовершенство представленной системы в плане того, что для данных уже не будет носителя нормального. поэтому это важно.
не знаю никаких багов, связанных со сжатием виджетайзером, тем более - если речь идет о том, что фатал именно в полной версии. сравни код, мб оптимизатор что-то поменял
0
21
7 лет назад
0
Господи, ну что там за лимит-то еще такой, подробнее можно?
Но все равно переместить CloneAbility не проблема, просто не вижу смысла из-за все-таки НЕ наиглавнейшей задачи в XXX-й раз изменять код (у ульта очень большой кд, он слишком часто юзаться не будет, даже с этим лимитом мифическим "сотен" там не наберется, если за одно использование пройдет 10 клонабилитей, + любая абила, на которую ульт уже воздействовал, клонабилити новых уже НЕ вызывает, т. к. по ифзенэлсу не проходит).
Фатал в основной карте происходит после ОДНОГО юза ульты и ОДНОГО увеличения ренджа (т. е. вызывается десять клонабилитей). Точнее, его достаточно, чтобы после выхода из вара был фатал. Все еще уверенность, что дело в этом "превышении лимита"?
Зачем вообще, еще раз, юзается функция клонабилити и что будет, если ее не юзать? Вот почему, например, в основном мемхаке есть функции, которые просто меняют параметры, а тут еще необходима вот эта клонабилити? Проконсультируйте, если не трудно.
4
16
7 лет назад
4
ClotPh:
Господи, ну что там за лимит-то еще такой, подробнее можно?
данные способностей, за редким исключением, хранятся в куче - объекте памяти, куда сбрасывается всё что угодно. когда способность первый раз запрашивается, движок создает под неё объект и размещает в куча память равную количеству уровней * 15 или сколько там полей на уровень. Затем он начинает компилировать абилку так, чтобы в любой момент можно было получить инфу о том, какие параметры нужны сейчас.
Например, у тебя болт с 10 уровнями. Как и все скиллы, он хранит ссылку на свои данные внутри себя. двиг идет туда, зная уровень, который щас-щас вот кинут. В определенных адресах этой таблицы-структуры данных лежат длительность и урон. А перед этим идет ссылка на точный адрес начала данных, для страховки.
И вот ты такой хочешь изменить абилку чисто для себя, например - для того, чтобы у конкретного героя абилка имела половинный манакост. При этом абилка может быть у кого-то еще, но у этого кого-то манакост резаться не должен. Если ты изменишь мк локально, поймаешь десинк, если дойдет до сравнения манапула. ПОэтому используется клонирование.
Клонирование основано на том, что создается изначально в редакторе/слк Х способностей с У уровней. Но вместо того, чтобы хранить свои данные в своих структурах, здесь автор записывает вместо стандартных значений те, которые нужны для клонированной абилки. Затем он подменяет ссылку, стоящую у болта, на ссылку, указывающую на структуру абилки-подмены. В результате получается два болта - один берет инфу из одного места, остальные - из другого. Эта технология вполне законна, но если ты выйдешь за лимит, и у тебя не будет споосбностей, на место которых можно склонировать данные, операция не удастся.
Болт 1: бла бла бла ссылка на инфу блабла
Болт 2: бла бла бла ссылка на другое место блаблалба
В твоем случае "другое место" могло быть занято. А может, и косяк в коде автора. Я данный прием не использую, поэтому судить не могу. Просто по опыту предполагаю самое очевидное - неправильное внедрение, раз у автора работает.
ну и да, если у тебя абилка гарантирвоано не повторяется, то и клонировать её не надо, очевидно. это так, мелочи уже
0
21
7 лет назад
0
Ладно, спасибо... Пока выяснилось, что если CloneAbility не писать, карта просто не запускается (ну примерно этого и ожидалось).
0
16
7 лет назад
0
ClotPh:
Ладно, спасибо... Пока выяснилось, что если CloneAbility не писать, карта просто не запускается (ну примерно этого и ожидалось).
эти факты друг с другом не связаны примерно никак, ибо при запуске анализируется только синтаксис, а не корректность
0
6
7 лет назад
0
ClotPh:
Ну код станет оптимальнее, ок, но не в этом же дело сейчас.
Все-таки мне кажется, что это из-за виджетайзера. Потому что он мне так уже уничтожал москитных даммиков, считая их "неиспользуемыми объектами", а мне потом разбираться, почему вместо файерболлов пустота летала.
Он, наверное, что-то там корежит в данных способностей при сжатии.
Потому что коды ведь одинаковые в тест-карте и в основной? (Если нет - пальцем на различия). А в тест-карте не фаталит, а в основной фаталит. А основная отличается:
  • Тем, что в ней дохрена всего;
  • Тем, что сжималась виджетайзером и оптимайзером.
Влияет ли первая причина? Вряд ли. Вывод...
***
Нде. Чушь какая-то. Дошло сейчас прогнать тест-карту через виджик и оптимайзер (т. е. протестировать так же, как основную) - нет фатала.
Оптимизация одинаковая. Код спелла одинаковый.
Одна карта фаталит вар после выхода из него, если спелл юзается, другая нет. Втф?
А что вообще будет, кстати, если клонабилити не писать?
Функция не подействует, код не скомпилируется или?...
все из-за malloc, варик не может очистить память из данного диапазона. На днях выложу код, делал через абилу с 1кк лвл, туда и писал данные, фаталов после этого небыло (главное не создавать такую абилу в редакторе)
function CloneAbilityData takes integer a returns nothing 
local integer Address = malloc(23*4)
local integer AddressTabl = malloc(22*4+26*4*GetAbilityMaxLevel2(a) + 4 ) //Вот сдесь надо отказаться от malloc, и проблема решится.
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
0
21
7 лет назад
Отредактирован ClotPh
0
Ну т. е. функцию CloneAbilityData надо переписанную потом будет просто вставить?
Ок, жду, спасибо.
0
21
7 лет назад
0
Есть еще смысл ждать? Потому что самостоятельно вообще не представляю, как заменить эти 2 строчки.
0
16
7 лет назад
0
алекс, закинь обновленную функицю, там же не высшая математика, легко принцип пересказать
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.