Выход нового, 1.24, патча стал проблемой для многих игроков Warcraft’а, они потеряли возможность играть в большинство нестандартных карт. Это случилось из-за фикса старой ошибки близов, называемой Return Bug, благодаря которой мы могли получить Handle любого объекта, а некоторые хакеры открыть окно cmd. Взамен они дали возможность пользоваться хеш-таблицами, которые намного удобнее и быстрее (более подробно про хеш-таблицы можно узнать на страницах Wikipedia). В данную таблицу можно записывать абсолютно любые игровые объекты или переменные. Это может быть использовано для создания оригинальных способностей юнитов или дополнительных характеристик, таких как усталость, сытость, температура и т.д. Если у вас есть хотя бы минимальные знания Jass'a, то продолжим.
Как вы видите функций довольно много и рассказывать про каждую отдельно не имеет смысла, поэтому я расскажу лишь про основные.
Использование
Инициализация
Самой главной функцией из этого списка является функция “InitHashtable”. С помощью неё мы инициализируем хеш-таблицу для последующей работы с ней. В начале создадим глобальную переменную типа “Хеш-таблица (Hashtable)” и назовём её “Hash”, затем присвоим ей нужное значение: [code=jass]set udg_Hash=InitHashtable() [/code]
Получение Handle объекта
Если мы хотим присваивать объектам какие-либо значения, то нам необходим хендл данного объекта. Получить его мы можем с помощью функции “GetHandleId”. В качестве аргумента мы передаём любой игровой объект и получаем число типа “Целочисленное (integer) ”. Пример:
[code=jass]local integer ObjectHadle set ObjectHadle= GetHandleId(udg_Unit)[/code]
В данном примере мы присвоили переменной “ObjectHadle” хендл юнита, заранее занесённого в переменную “udg_Unit”
Сохранение значений
Теперь когда таблица создана и мы умеем получать ссылки на объекты в неё можно записывать любые значения. Для записи используются функции с префиксом “Save” (например SaveInteger или SaveUnitHandle) из списка предоставленного выше. Простейшим примером использования данных функций является запись числа для юнита:
В первом аргументе мы передаём функции “SaveReal” хеш-таблицу (“udg_Hash”), во втором хендл юнита “udg_Unit” (созданного ранее и записанного в переменную “udg_Unit”), для которого мы хотим записать это число, в третьем “номер ячейки” данного числа(“0”), ну а четвёртым мы передали само число(“1.00”). Если мы захотим записать другие числа, то мы можем либо перезаписать его, использую функцию:
Для загрузки из таблицы используются функции с префиксом “Load” из списка предоставленного выше. Давайте напишем функцию для загрузки числа из прошлого примера и вывода его на экран:
[code=jass]local real test set test=LoadReal(udg_Hash, GetHandleId(udg_Unit), 0) call BJDebugMsg(R2S(test))[/code]
Сначала мы указываем функции хеш-таблицу (“udg_Hash”), затем даём ссылку на объект (“GetHandleId(udg_Unit)”), а в конце номер ячейки (“0”), из которой мы хотим получить это число. После выполнения этой функции переменная “Test” должна стать равной “1.00” и на экране появится соответствующая надпись
Проверка
Что бы проверить занята ли ячейки или нет пользуются функциями:
[code=jass]native HaveSavedInteger takes hashtable table, integer parentKey, integer childKey returns boolean native HaveSavedReal takes hashtable table, integer parentKey, integer childKey returns boolean native HaveSavedBoolean takes hashtable table, integer parentKey, integer childKey returns boolean native HaveSavedString takes hashtable table, integer parentKey, integer childKey returns boolean native HaveSavedHandle takes hashtable table, integer parentKey, integer childKey returns Boolean [/code] В качестве аргументов принимаются хеш-таблица, хендл объекта и номер ячейки. Если запись в ячейке уже существует, то вернётся значение “true”, если же ячейка свободна, то функция вернёт значение “false”. Пример:
Бывают ситуации когда необходимо удалить запись из ячейки. Например, стереть запись, содержащую какое-либо число, и записать в эту ячейку ссылку на таймер. Для этого используются функции:
Как и в прошлом примере, в качестве аргументов, мы указываем хеш-таблицу, ссылку на объект и номер ячейки.
Полное удаление записей
Последние 2 функции, которые мы с вами разберём, будут “FlushParentHashtable” и “FlushChildHashtable”. FlushParentHashtable позволяет удалить нам абсолютно все записи из хеш-таблицы. В качестве аргумента указывается только очищаемая хеш-таблица. После использования донной функции хеш-таблицу приходиться инициализировать заново! Пример:
А вот FlushChildHashtable нужна для удаления записей из одного объекта. Рекомендую использовать данную функцию, например при удалении юнита, так как даже есть вы удалите юнита функцией “RemoveUnit”, то его значения останутся в хеш-таблице. Пример:
Рекомендую вставлять такой код в любую карту, где вы работали с хеш-таблицами, по-моему очень удобно:
[code=jass]function Flush_Unit takes nothing returns nothing local unit u = GetTriggerUnit() call FlushChildHashtable(<Хеш-таблица>, GetHandleId(u)) set u=null endfunction
function InitTrig_Flush_Unit takes nothing returns nothing local trigger t = CreateTrigger() call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_DEATH ) call TriggerAddAction( t, function Flush_Unit ) set t=null endfunction[/code]
Примеры использования
Взрыв юнита
Примером использования хеш-таблиц может служить простой пример со взрывом юнита. Например мы хотим, что бы юнит взорвался после каста заклинания. Это очень просто скажите вы. Но если нужно чтобы он взорвался через 5 секунд после каста заклинания? Особо остроумные могут конечно использовать действие “Wait”, но работа с таймерами куда лучше, так как wait может повести себя абсолютно не предсказуемо, вплоть до того что действия после него просто не будут выполняться.
[code=jass]function Explode takes nothing returns nothing local timer t=GetExpiredTimer() //Получаем таймер, вызвавший данную ф-цию local unit u=LoadUnitHandle(udg_Hash, GetHandleId(t),1) //Загружаем нужного нам юнита
call ExplodeUnitBJ(u) //И взрываем его <img rel="usm" src="http://warcraft3ft.info/image/smiles/smile.gif" border="0" align="absmiddle" alt=":)"> call FlushChildHashtable(udg_Hash, GetHandleId(t)) //Удаляем записи таймера
call DestroyTimer(t) //Обнуляем переменные и “разрушаем” таймер set t=null set u=null endfunction
function Trig_Explode_Actions takes nothing returns nothing local timer t=CreateTimer() //Создаём новый таймер local unit u=GetSpellAbilityUnit() //Заносим в переменную юнита-кастера
set udg_Hash=InitHashtable() //Инициализируем хеш-таблицу, если ранее это действие не выполнялось call SaveUnitHandle(udg_Hash, GetHandleId(t), 1, u) //Сохраняем ссылку на юнита “внутри” таймера call TimerStart(t, 5.00, false, function Explode) //Запускаем таймер
set t=null //Обнуляем переменные set u=null endfunction
function InitTrig_Explode takes nothing returns nothing local trigger t=CreateTrigger() call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_CAST ) call TriggerAddAction( t, function Trig_Explode_Actions ) set t=null endfunction [/code]
Gyver, я тебя щас Эллесар, Ващет я ещё писал про call FlushChildHashtable(udg_Hash, GetHandleId(udg_Unit)) Ты сделай абилку, которая мувает объект без неё и посмотри скока раз ты её кастанёшь до лагов
Добавлено (02-12-2009, 16:14) --------------------------------------------- ЗЫ А вы сам вообще чёнеть пишите или всё с хгма копипастите?
Эллесар, Ващет я ещё писал про call FlushChildHashtable(udg_Hash, GetHandleId(udg_Unit)) Ты сделай абилку, которая мувает объект без неё и посмотри скока раз ты её кастанёшь до лагов
Можно и без ХТ обойтись без лагов)
база паролей: https://yadi.sk/d/mdDhWuvPcTSKw бекап сайта от 26.12.2010 https://yadi.sk/d/L3xNpibbiHpYE
В данную таблицу можно записывать абсолютно любые игровые объекты или переменные. Это может быть использовано для создания оригинальных способностей юнитов или дополнительных характеристик, таких как усталость, сытость, температура и т.д. Если у вас есть хотя бы минимальные знания Jass'a, то продолжим.