Почему единожды? Я говорю, если локальные таблицы постоянно создавать. В цикле например или на каких-то событиях.
Создавать хештаблицу локально? Что? Зачем? Это глупость полнейшая. Hanabishi:
Непонятно какая речь про жалкость 40 байт, если люди умудряются память даже точками засрать, которые казалось бы имеют размер еще меньше.
Это засирается утечками и косячностью локальных хендлов, да и ровняться извини на рукожопов - не думаю что имеет смысла. Hanabishi:
Суть в том, что если есть объект, который можно создать, но нельзя удалить, это утечка. В варе такого дофига.
Который адекватные люди создают единожды, собственно никакой утечки нет. И повторюсь, если очень надо, тот мемхаком можно очистить занятую ХТ. Просто я не вижу в этом смысла, пытаться делать систему под тех, кто не понимают как использовать Хештаблицу (аля БД) и твой юзкейс ну вообще не встречается нигде (я лично такого никогда не видел).
Спустя 10 лет еще кому-то не пофиг? Вообще я в комментах отвечал, что имелось в виду.
У нас нет действия типа DestroyHashtable, то есть таблицы нельзя удалять. Поэтому если в каком-то действии постоянно создаются таблицы, память будет течь.
40 байт единожды потерять, не знаю даже. Если оно очень надо, то я могу написать код для мемхака для удаления хештаблицы и очистки индекса. Но это даст ровно 40 байт и всё, что банально не скажется ни на чём.
То бишь 0x34 байта выделены всегда, каждая ХТ по стандарту - это 0x28 байт опять, и каждая новая ячейка - 4 байта (исключение boolean (1 байт) и string (каждый символ = 1 байт)).
Здесь главный вопрос деаллокается ли память обратно при удалении элементов. Если да, то утечку памяти хотя бы можно минимизировать очисткой. Если нет, то это вообще жопа и мое утверждение верно на 100%.
Да, она очищается при очистке ячейки, то бишь именно Flush/RemoveSaved. И нет, ни первое ни второе утверждения не верны. Это как сказать "ну ты же используешь глобалку, вот 4 байта всегда заняты". Что конечно частично верно, но на деле не даст разницы никакой, а почти во всех картах есть туча неиспользуемых глобалок, что явно превысит 40 жалких байт, которые хештаблица занимает единожды.
Если же реально эти 40 байт на столько прямо необходимы, то тогда уже проблема не в отсутствии удаления хештаблицы, а в самой карте. (:
П.С. поправка моего предыдущего коммента, каждая ячейка это всё-таки 4 байт. (и да, я попутал ячейку и тип переменной), То бишь сообщение про вес - это про сам тип переменных, а не ячейки.
Почти все мифы с хайва и пошли... да и их "таймер" зачастую выдавал бредовые значения, по которым у них GetWidgetX был быстрее GetUnitX, сейчас я это протестирую, не вопрос. И да, сравнение опять же не честное, ибо 'cnst' по байтам превосходит любой индекс массива. Поправка: надо было мне в начале посмотреть таки тред, там наоборот отстаивают позицию по хештаблицам и опровергают басни про её медлительность, спасибо в общем за ссылку.
Но чёрт с ним, вот результаты:
Возьмём поделим 2мс на 5000, получаем 0.0004мс, что является 400нс или же 0.0000004 секунды. Так как у нас +-1мс уходит на массив, то разница по факту 200нс или же 0.0000002 секунды. Потому я ещё раз спрашиваю, где вы почувствовали такую гигантскую разницу, когда даже 5000 итераций дают жалкую погрешность? И я повторюсь - это не честное сравнение и если взять напрямую системы, весы явно отойдут от структур.
Я надеюсь на этом вопросы отпали?
Ну и тем, кто хочет проверить самим результат, прикерил код для Мемхака:
П.С. даже Лич в целом разделяет мою точку зрения: "Minding that that been 5k operations and yet it took <10 ms, it barely matters in real life, but it does matter for every snowflake."
PT153 ещё раз спасибо за полезную ссылку, остальным бы не помешало её посетить и вчитаться. :)
> Приведу в пример ту же систему снарядов, ты же что-то будешь проверять, чтобы убедиться что снаряд нужно двигать, верно?
это всё равно что после выгрузки юнита из хэш-таблицы проверять, что он != null
в общем ты не понял что я сказал. У тебя есть цикл, который перебирает структуру, и есть проверка хоть какая-то, может ты делаешь без неё но большинство наработок проверяют допустим наличие юнита, флага, или длительности и т.д.
цикл не делается от 0 до 8191, он делается от минимального и максимального значения, которое варьируется от кол-ва "запусков", если что-то не нужным становится, на его место ставят последнее, а максимальное значение снижают на единичку
Зависит от наработок, да и я показал, что даже при 6 элементах уже по факту задержка не маленькая. В общем, я привёл доказательства, пояснил всё, что только можно было, теперь дело за тобой и другими проверить эти структуры, привести примеры с указанием скорости, ибо пока что это всё терпит без практического доказательства.
Unryze, ну простейший цикл из 6 значений всё-таки, таймер перемножить на 6, т.е. 8х6 и выйдет больше результат, пускай это и не в одном потоке должно быть
массив по индексу никто не проверяет на != null
Приведу в пример ту же систему снарядов, ты же что-то будешь проверять, чтобы убедиться что снаряд нужно двигать, верно? Я писал об этом, и привёл простой пример. По таймеру, оно работает отдельно и у него будет своя отдельная задержка, каждый таймер, как и триггер "выстреливает" отдельно. И нет, оно не будет напрямую множится, это нонсенс. Таймер даже на .0 срабатывает медленнее цикла, то бишь оно всегда будет нагружать "меньше".
Я просто не знаю как уже до вас донести, что эти басни в реальном мире сводятся на нет, и фактическая разница скорости на столько незначительна, что ну нельзя говорить о полном преимуществе структуры или же хештаблицы. Просто как по мне, хештаблица выигрывает удобностью (стрингхеш всё же позволяет удобно "обзывать" ключи), модульностью (чики-брики легко перенести) ну и в целом дополнительным API без танцов с бубном.
может мне пример работы с циклом и одним таймером показать, вместо хэштаблицы как используют
Да я могу тебе тоже накидать этих прелестей и показать тебе что по скорости они отваливаются в одно место. Просто я не затираю никому, что нужно взять и отказаться от структур, я хочу чтобы фанатики структур перестали извини триндеть, что хештаблица такая медленная и непригодная, не более.
Я просто хочу увидеть от кого-то пример, где "медленность" хештаблицы наглядно даст о себе знать, я тут извините распинаюсь и кидаю тесты с пруфами, а в ответ ничего так и не получил, чтобы опровергло мои высказывания или же подтвердило бы правоту мнения по поводу структур. :(
думаю стоит доработать её, а именно информацию о ресурсоёмкости хэш-таблиц
Что за ресурсоёмкость
Речь об этом высказывании:
Что не является правдой, ибо память выделятся динамически для каждой ячейки. Есть изначальный размер CGameHashTableManager (который существует по факту всегда), ну и каждая ХТ - имеет свой вес:
Размер Хештаблицы:
То бишь 0x34 байта выделены всегда, каждая ХТ по стандарту - это 0x28 байт опять, и каждая новая ячейка - 4 байта (исключение boolean (1 байт) и string (каждый символ = 1 байт)).
Замечу, что достаточно часто, одной из первых оптимизаций хэштаблицы, которые можно, а часто и полезно, использовать - замена стрингхэшэй на тип кей из вжаса и "Массивы" с камими-то большими смещениями, ну типа на 100к, для каждого набора тех данных, которые хочется хранить, этого примерно всегда будет достаточно, и даст какой-то плюс по производительности и количеству написанного кода.
Но предположу, что возможно, одной из вторичных затрат при использовании систем, в которых на каждый объект приходится отдельный таймер, и, которые так хорошо идут с хэштаблицами, являются затраты на старт отдельного потока при срабатывании таймеров, что по моему скромному мнению должно также требовать некоторых ресурсов.
По большей части согласен, а по поводу потока, ресурс будет выделяться всё-равно меньше, ибо идёт банальный вызов функции при тике таймера (таймеры находятся в общем массиве), то бишь 200нс (обычный вызов). Это к счастью не форгрупп, который создаёт ещё и булэкспр внутри движка и ещё кучу прелестных операций. rsfghd:
Unryze, ну.. стоит не забывать о получении истекающего таймера, получение его айди, потом ещё повытаскивать значения оттуда, сохранить эти значения, уже немало так лишних действий
да и в конце нужно удалять и очищать таймер, а переменные обнулять, половину из этого как раз структура + хэш-таблица нивелирует
set p = GetHandleId( GetExpiredTimer( ) ) даёт:
8 мс задержки на 10000 повторов, то бишь 800 нс на каждый вызов, смотрим на простейший цикл допустим из 6 значений и результат с ним:
И бац, нагрузка уже больше. Далее добавляем проверки что "массив под этому индексу != null" и прочие финтифлюшки структур и теряем ещё больше скорости. Я же не просто так сделал функцию бенчмаркинга, чтобы при малейшем сомнении, каждый мог взять и всё сам проверить. :)
К слову если взять допустим меньше, допустим 3 значения:
Получаем в среднем неплохую разницу, но опять же, чем больше всякой мути в коде, тем разница будет расти. В случае с хешем, мы "теряем" производительность скорее на дополнительных таймерах, но проверить их влияние сложнее, ибо толком не за что цепляться.
В целом можно сойтись на компромиссе, что и то и то "приемлемо" и по скорости равно, где-то свои плюсы, где-то свои минусы, но итог как вы видите варьируется.
Unryze, что-то я уже начинаю сомневаться, всё-таки циклом перебирать массив лучше чем на каждый снаряд делать по таймеру и каждый раз что-либо доставать оттуда и сохранять, исключение хэш-таблица + структура, немного оптимизированный вариант
Чем оно более оптимизированно? Когда таймеры можно утилизировать и вообще удалять и очищать. На крайний, окей, можно сделать и "структуру" на хеше, которая не будет особо уступать по скорости (вопрос только зачем оно).
Мне сделать тест на 1000 таймеров что ли? :D Просто если исходить из реального (а юзкейсы со снарядами - это 0.1%), то сложно дойти до случая, где нагрузка будет столь велика, что нужно будет бороться за наносекунды, что я и пытался пояснить. Я делал на мемхаке итерации куда более сложных функций, нагрузки которые достижимы лишь синтетически, потому на деле добраться до таких диких нагрузок практически невозможно...
Как-то очень поверхностно что ли прочитал статью, процитирую кусочек: "Рассмотрим их фактические задержки, 3 мс / 10000 = 300 наносекунд и 13 мс / 10000 = 1300 наносекунд, то бишь борьба идёт за 1000 наносекунд, что является 0.001 мс или же 0.000001 секунды. Потому мне лично сложно представить, где эта разница даст о себе знать и как часто делается 10000 повторов или же вызовов чего-либо."
ну а теперь возьми, да забей хеш таблицу различными данными. чем больше она занята тем больше займет поиск по ключу.
Хештаблица - это не массив. Сколько ты её не забивай, скорость не изменится. Откуда вы эти басни штампуете - не понимаю.
а потом представь что это какая нибудь система движения, где кроме этого происходит карнавал другого рода, и уже это начинает вызывать определенные вопросы
Опять же 300нс, или же 0.00000003 секунды погоды не делают, и опять же, как-то же игра всё держит на хештаблице внутри движка? :)
Забыл добавить, что я писал не о просто "сткрутурах" в целом, а при применении их в MUI наработках. Ну и хочется добавить, что лимит строго по индексу - куда хуже, чем возможность использовать уникальный хендл объекта как ключ, что убирает мягко говоря геморрой индексации.
И маленькая поправка, есть системы на структурах, где есть "счётчик", который увеличивается и уменьшается, что конечно же убирает нужду в итерации 8192 раза, но даже так, будут лишние итерации, нужда в нахождении свободного индекса и т.д. В общем и там и там - свои минусы
0.00000003 секунды и только если это единичный вызов, системы на структурах медленнее, ввиду лишних циклов и итераций, прочитай пожалуйста что я пишу внимательно.
так а где развенчивание мифа про то что хеш таблица медленная? ты же это сам и показал, кек, лишь подтвердив что она реально медленнее
Как-то очень поверхностно что ли прочитал статью, процитирую кусочек: "Рассмотрим их фактические задержки, 3 мс / 10000 = 300 наносекунд и 13 мс / 10000 = 1300 наносекунд, то бишь борьба идёт за 1000 наносекунд, что является 0.001 мс или же 0.000001 секунды. Потому мне лично сложно представить, где эта разница даст о себе знать и как часто делается 10000 повторов или же вызовов чего-либо."
Ну и поясню немного подробнее, если сравнивать ровно 1 массив и ячейку хеша, то да, массив конечно быстрее. Но если дойти до структур, где итерация идёт на все 8192 значения (0 - 8191), то скорость структуры в РАЗЫ будет ниже, если очень нужно, могу даже замерить, но как не крути, модульность хеша + его простейший перенос делает его по всем характеристикам лучше, чем vJass структуры.
Забыл добавить, что я писал не о просто "сткрутурах" в целом, а при применении их в MUI наработках. Ну и хочется добавить, что лимит строго по индексу - куда хуже, чем возможность использовать уникальный хендл объекта как ключ, что убирает мягко говоря геморрой индексации.
И маленькая поправка, есть системы на структурах, где есть "счётчик", который увеличивается и уменьшается, что конечно же убирает нужду в итерации 8192 раза, но даже так, будут лишние итерации, нужда в нахождении свободного индекса и т.д. В общем и там и там - свои минусы, но утверждать что Хеш прямо МЕДЛЕННЕЕ - ну не знаю даже. Опять же лучшее сравнение нативки вс МемХак функции, разница в 60-70 раз порой, но это не делает их прямо невозможными для пользования, ибо в реальной ситуации, подобные нагрузки недостижимы и эти псевдоразницы скорости - никогда себя не проявят.
Unryze, ну тут скорее тема обсуждения: насколько критично плодить обёртки ради читаемости и поддерживаемости кода)
Зависит от метода использования, фактически оно не несёт столь значительного замедления, чтобы отказываться, да и всё же большинство наработок - это не только обёртки, а полноценные функции. А вот использовать BJ обёртки, когда они не несут фактического отличия от нативок - это всё же глупость, как я считаю. То бишь если это SetUnitAbilityLevel и SetUnitAbilityLevelSwapped (зачем использовать BJ функцию, если разница лишь в местоположении аргументов).
А так читаемость > псевдоскорость, потому даже если нагрузка увеличится на 1000нс - это всё-равно жалкая разница, так как это не сравнится с тем, на сколько функции МХ медленные. Когда нативка 2-10мс на 10000 повторов, функция мх - 140-160 и порой больше. Потому все эти псевдозакосы про скорость - как по мне глупости. Но самая большая глупость всё же - это старая добрая дилемма хеша и структур... с которой я всё ещё мягко говоря в шоке, что кто-то умудрился без доказательств подтвердить разницу в скорости (которая даже не ощутима) и народ повёлся. :(
Ещё ходил такой слушок, что вызов функции из другой функции несёт дополнительную нагрузку на JASS-машину. Этот миф появился из-за bj-функций, которые в себе вызывают аналогичную нативную функцию.
Ну, это не совсем миф, но и не совсем точная формулировка. Всё сходится к байткоду, опять же. Рассмотрим такой вариант:
ClearTextMessages и
function ClearTextMessagesMy takes nothing returns nothing
call ClearTextMessages( )
endfunction
Получаем:
Выходит, что добавилось 2 МС на 10000 повторах, что опять же логично, рассмотрим байткод:
вызов нативки
15000000
00000325
Вызов функции:
16000000
00000A10
Изначальный вызов (если наша функция напрямую вызывала бы код нативки, а не саму нативку, скорость была бы равна). Однако мы из функции затем вызываем уже саму нативку:
15000000
00000325
И того, у нас двойной вызов, то бишь:
16000000
00000A10
15000000
00000325
Что в итоге добавило 200 наносекунд на каждый вызов или же 2 мс в общем.
Думаю добавлю это в статью тоже, ибо это технически не миф, а факт, ибо обёртки всегда будут добавлять задержку, ибо добавляется байткод. :)
Для ХП баров ничего не завезли? Вообще как-то можно получить указатель на хп-бар юнита, или всё гораздо сложнее и нужна отдельная DLL?
pUnit = ConvertHandle( unit )
pPreselectUI = ReadRealMemory( pUnit + 0x50 )
pStatBar = ReadRealMemory( pPreselectUI + 0x0C ) это CStatBar, расширение CSimpleStatusBar
Так как pStatBar - это расширение симплфреймов, то большинство функций оттуда уже будет работать. Далее:
pStatBarTexture = ReadRealMemory( pStatBar + 0x144 ) Это CSimpleTexture.
Все хотелки реализуемы, было бы кому оно нужно и был бы он готов заплатить за моё время, мне уже лень делать больше, чем я уже сделал на одном энтузиазме. :)
Правильно ли я понимаю, что герою такая способность не даст ничего?
Верно, ибо герой уже выполняет эти функции, а эта способность имитирует принцип цели "герой", не меняя напрямую тип юнита, тип брони и т.д.
Кстати я говорил об Amim способность, но я так думаю она идентична
'Amim' - совершенно другая способность:
Список равкодов гиганта: Atau,Agra,Arsk,Assk,Aien
Способность по твоему описанию: "Сокращает время действия отрицательных эффектов, дает невосприимчивость к некоторым способностям." - именно 'Arsk':
А 'Amim' - Spell Immunity - даёт полный иммунитет ко всем заклинаниям, схожее есть у големов, драконов и Архимонда, то бишь 'ACm2' (Архимонд), 'ACm3' (дракон) и 'ACmi' (нейтральный/големы) ещё есть 'AImx' - иммунитет от предмета.
Юнит с этой пассивкой будет считаться как цель типа "герой", собственно заклинания (большинство из них) которое делится на nduration (нормальная длительность) и hduration (геройская длительность) будут "задеты". Пример: 'Aslo' - замедление, имеет hduration 10 и nduration 60, значит гиганта замедлит на 10 секунд, а не на 60.
Ну и заклинания которые можно применять СТРОГО на обычных юнитов также не будут работать на гиганта, ибо как я и написал выше, он будет считаться как цель типа герой.
Thezolotoi: Ну, вообще было бы желательно если бы ты ещё и показал, какую именно статью ты читал и какой код ты вообще написал. Я буду исходить из того, что ты наверное не понял вообще ничего (надеюсь не в обиду).
Итого, начнём с простого, создания самого диалога. Всё что нам нужно - это CreateDialog и DialogAddButton, краткий пример ниже.
Всё довольно просто, ведь так? Теперь добавим триггер и действие, для этого нам нужно:
Ещё код
call TriggerRegisterDialogEvent( trigger, dialog ), где dialog = это не кнопка а именно весь созданный диалог, к которому мы добавляем кнопки.
call TriggerAddAction( trigger, function FUNCTION ) где FUNCTION - это допустим ModeDialogAction:
globals
dialog Dialog = null
button DialogButton1 = null
endglobals
function ModeDialogAction takes nothing returns nothing
if GetClickedButton( ) == DialogButton1 then
// что-то если нажатая кнопка = нужной кнопке.
endif
endfunction
function TestDialog takes nothing returns nothing
local trigger t
if Dialog == null then
set t = CreateTrigger( )
set Dialog = CreateDialog( )
set DialogButton1 = DialogAddButton( Dialog, "Опция 1", 0 )
call TriggerRegisterDialogEvent( t, Dialog )
call TriggerAddAction( t, function ModeDialogAction )
endif
set t = null
endfunction
Теперь у нас получен простенький вариант проверки нажатой кнопки, можно делать даже массив из кнопок button array, чтобы не впихивать каждую кнопку, а сделать вот так:
И опять код :)
globals
button array Buttons
endglobals
function ModeDialogAction takes nothing returns nothing
local integer i = 0
local integer max = 10
local button Button = GetClickedButton( )
loop
exitwhen i > 10
if Button = Buttons[ i ] then
// что-то делаем тут
endif
set i = i + 1
endloop
set Button = null
endfunction
А по поводу, где "редачить" Jass, всё в том же World Editor, просто нажимаешь на нужный тебе триггер -> Правка -> Преобразовать в Текст. И вуоля ГУИ-ужасня превратилась в Jass код.
Replay Panel is now also modifiable by Upgraded UI.
Fixed some of the UI elements not being able to hide if Upgraded UI was disabled.
*NEW FEATURE* Ally Skill view, this will show abilities of units of your allies along with their cooldowns.
Note: you are not able to "ping" data of your allies skills, as that is simply a bit too much.
Replay Panel is now a separate option in UI Modification section, meaning you will no longer have to toggle Ability Buttons to make it appear/disappear, etc.
Raised priority of CSimpleConsole (GameUI), CUpperBar (Console Top Left buttons), CResourceBar, CCommandButtons and CSimpleFontString (Inventory text).
Note: this blocks the Healthbars, etc. from passing through the UI. The only thing that cannot "block" it remains the portrait...
Lowered the priority of COccupUI (cargo statbar) from 4 to 1, now it will be "stopped" near the UI just like HP/MP bars.
*NEW COMMAND* kill, this command will kill any selected unit/item/destructable.
These buttons are now available for KeyBinds/Hotkeys:
"Scroll"
"Pause"
"Insert"
"Delete"
"Home"
"End"
"PageUp"
"PageDown"
"+"
"-"
"NumPad-"
"NumPad+"
"NumPad/"
"NumPad*"
"NumPad."
"\\"
"/"
"."
","
"\""
";"
"["
"]"
Fixed CMinimap offsets for 1.27b, this is the reason why it was failing to resize itself.
Скачать можно всё так же через Гитхаб или же автоматическим обновлением программы.
Курсор является CCursorFrame является CSpriteFrame и использует CSpriteUber, в МемХак я не завозил адреса и т.д. Но технически можно заменять модель спрайту напрямую (однако игра часто перезаписывает модельку, когда допустим делается прицел, затем возвращается в стандарт по пути из fdf.
Как вариант, найти путь фдф и менять его локально, чтобы при обновлении модели получилась новая. Либо по таймеру каждый раз обновлять модельку.
Оффсет CSpriteUber у CCursorFrame - 0x178 и 0x18C (но оно является двойным поинтером). Потому, чтобы получить реальный спрайт, то нужно сделать так:
ReadRealMemory( ReadRealMemory( cursor + 0x178 ) ) или же ReadRealMemory( ReadRealMemory( cursor + 0x18C ) ), полученный адрес будет является CSpriteUber и в 1.7 будет полноценное разделение спрайтов на:
CSpriteBase (будет содержать общие функции)
CSpriteMini (функции для CSpriteMini, а это предметы, разрушаемые и декорации).
CSpriteUber (функции для CSpriteUber, а это юниты, эффекты и трекейблы, ну и все фреймы, которые юзают спрайтов)
Fixed LocalPlayerId variable in CGameWar3 (it's a int32_t value, that is shifted 2 bytes to the right to get the id, I was directly moving int16_t to int32_t which would never work for any slot other than red).
Fixed Fatal Error of WFE with KLoader multi-window.
Fixed never-ending timer PopulateNavitesListTimerProc, which was responsible for adding all natives to std::map, so it can be re-used all the time, instead it was re-doing that indefinitely...
Added QuestButtonHighlight resizing for Enhanced UI, it used to be "fullsize" regardless of the selected mode.
Unryze
Я отыскал в закоулках своей памяти карту, в которой возникала проблема из-за таких утечек. Там таблица хэндлов раздувалась примерно до 400 мегабайт, и, замечу, одним куском, с реаллокацией чего сложности возникнут раньше чем с кусками маленькими.)
Есть даже сейв, с которым можно сразу посмотреть проблему. Даже удивительно, что что-то такое сохранилось.
Изучил карту, но тут разница есть большая, там не только утечки создают новые хендлы (а точнее их id), очень много CreateNUnits и прочих утекающих bj функций. А так, в целом, да, можно на этой карте проверить "лечение" утечек, добавить нужные обнуления, заменить bj-мусор и сравнить результаты. Я более чем уверен, что разница будет колоссальная. Особенно если все триггеры смерти заменить одним.
Но не стоит забывать, что занятый вес карты - это не только хендлы - это ещё и все модели, эффекты которые привязаны к существующим юнитам, декорации и прочее. Но конечно, как не крути - эта карта кишит утечками и каждую секунду добавляется по 30-40 килобайт, порой и больше.
Редактирование: причём потребление памяти увеличивается даже когда по факту ничего и не происходит. Удивительная карта в общем.
Unryze, Ага, то есть, как я понимаю, иконки настраиваются в коде игры, видимо в game.dll ?
Я то хотел не просто расположение иконок поменять, а сделать панель приказов на 20 иконок, 5х4 чтобы было, ну и с размерами иконок чуть поменьше. И без мемхака, чтобы не было возможных дополнительных проблем. Чтобы такая панель была вшита в игру, как стандартная.
Без МемХака на младших патчах это сделать никак не получится. И да, это псевдокод game.dll. Не знаю как там в рефорджеде, но если там сделали во ФДФ, ну прикольно. :)
fdf - это темплейт, он не обязателен вообще. CCommandBar не использует fdf для местоположения в 1.26а-1.28ф:
Каждая кнопка прикреплена по оси X/Y используя CSimpleGrid. Однако если нужно поменять позицию кнопки - это можно делать по-отдельности, такое доступно в моём МемХаке. Можно сделать что-то такое:
Вся логика игры и World Editor, в Storm.dll находится вся логика работы с файлами, пакетами и прочим (на которую ссылается game.dll). В Рефорджеде эти дллки либо вшили в .exe либо перенесли весь код .dll в .exe.
Функция ReduceAbilityCooldown иногда работает только визуально: на UI кулдаун уменьшается, но кулдаун самой абилки при этом не изменился, и даже когда на UI уже нет кулдауна, абилка всё равно будет говорить, что пока нельзя применить. Это как-нибудь фиксится?
Проверил, ты видать слишком рано её вызываешь, если таймстемп не успел появиться, то и уменьшение кд будет по факту пустышкой. Но функция точно работает. То бишь надо применять её допустим с задержкой в .01 секунды, в идеале это будет выглядеть так:
Пример кода
globals
hashtable SpellCastTable = InitHashtable( )
endglobals
function AbilityEffectFunc takes nothing returns nothing
local timer t = GetExpiredTimer( )
local integer hid = GetHandleId( t )
call SetAbilityCooldown( LoadAbilityHandle( SpellCastTable, GetHandleId( t ), StringHash( "Ability" ) ), 1., "" )
call PauseTimer( t )
call FlushChildHashtable( SpellCastTable, hid )
call DestroyTimer( t )
set t = null
endfunction
function AbilityUsedHandler takes integer aid, ability abil, unit caster, widget target, real targx, real targy returns nothing
local timer t
if aid == 'AOsh' then
set t = CreateTimer( )
endif
if t != null then
call SaveInteger( SpellCastTable, GetHandleId( t ), StringHash( "AbilityId" ), aid )
call SaveAbilityHandle( SpellCastTable, GetHandleId( t ), StringHash( "Ability" ), abil )
call SaveUnitHandle( SpellCastTable, GetHandleId( t ), StringHash( "Caster" ), caster )
call SaveWidgetHandle( SpellCastTable, GetHandleId( t ), StringHash( "Target" ), target ) // Можно поменять на item/desctructable
call SaveReal( SpellCastTable, GetHandleId( t ), StringHash( "TargetX" ), targx )
call SaveReal( SpellCastTable, GetHandleId( t ), StringHash( "TargetY" ), targy )
call TimerStart( t, .01, false, function AbilityEffectFunc )
endif
set t = null
endfunction
function AbilityUsed takes nothing returns nothing
call AbilityUsedHandler( GetSpellAbilityId( ), GetSpellAbility( ), GetTriggerUnit( ), GetSpellTargetUnit( ), GetSpellTargetX( ), GetSpellTargetY( ) )
endfunction
function Init_TestAbilUsed takes nothing returns nothing
local trigger t
set t = CreateTrigger( )
call TriggerRegisterPlayerUnitEvent( t, Player( 0 ), EVENT_PLAYER_UNIT_SPELL_EFFECT, null )
call TriggerAddAction( t, function AbilityUsed )
set t = null
endfunction
А вот и результат:
JackFastGame Посмотри пример выше и попробуй сделать как я, сообщи что у тебя будет. :)
» WarCraft 3 / Hashtable - работаем с хеш-таблицей
Hanabishi:
Hanabishi:
Ред. Unryze
» WarCraft 3 / Hashtable - работаем с хеш-таблицей
Ред. Unryze
» WarCraft 3 / Jass MythBusters
Ред. Unryze
» WarCraft 3 / Jass MythBusters
Ред. Unryze
» WarCraft 3 / Jass MythBusters
Ред. Unryze
» WarCraft 3 / Hashtable - работаем с хеш-таблицей
0x28 = 40 байт.
Ред. Unryze
» WarCraft 3 / Jass MythBusters
rsfghd:
Ред. Unryze
» WarCraft 3 / Jass MythBusters
» WarCraft 3 / Jass MythBusters
Ред. Unryze
» WarCraft 3 / Jass MythBusters
» WarCraft 3 / Jass MythBusters
Ред. Unryze
» WarCraft 3 / Jass MythBusters
00000325
16000000
00000A10
00000325
00000A10
15000000
00000325
» WarCraft 3 / MemoryHackAPI
pPreselectUI = ReadRealMemory( pUnit + 0x50 )
pStatBar = ReadRealMemory( pPreselectUI + 0x0C ) это CStatBar, расширение CSimpleStatusBar
Ред. Unryze
» WarCraft 3 / Способность устойчивая кожа
Ред. Unryze
» WarCraft 3 / Способность устойчивая кожа
Ред. Unryze
» WarCraft 3 / Диалоговое окно и голосование
call TriggerAddAction( trigger, function FUNCTION ) где FUNCTION - это допустим ModeDialogAction:
» WarCraft 3 / MemoryHackAPI
Ред. Unryze
» WarCraft 3 / WFE - Warcraft Feature Extender
Github: github.com/UnryzeC/WFE-Release/releases
Note: you are not able to "ping" data of your allies skills, as that is simply a bit too much.
Note: this blocks the Healthbars, etc. from passing through the UI. The only thing that cannot "block" it remains the portrait...
Ред. Unryze
» WarCraft 3 / Как изменить модель курсора? memhack
CSpriteMini (функции для CSpriteMini, а это предметы, разрушаемые и декорации).
CSpriteUber (функции для CSpriteUber, а это юниты, эффекты и трекейблы, ну и все фреймы, которые юзают спрайтов)
» WarCraft 3 / WFE - Warcraft Feature Extender
Ред. Unryze
» WarCraft 3 / Jass MythBusters
» WarCraft 3 / Не найти фреймы в 1.26а
» WarCraft 3 / Не найти фреймы в 1.26а
» WarCraft 3 / Последовательность подгрузки MPQ и всё что с этим связано.
» WarCraft 3 / MemoryHackAPI