Сейчас 07:34:19 Среда, 23 ноября, 2011 год
[ x ] Главная ⇒ Форум ⇐ RSS Файлы Cтатьи Обои В о й т и   или   з а р е г и с т р и р о в а т ь с я


[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
Страница 1 из 11
Модератор форума: PUVer, FkoFF 
Форум о Warcraft 3 » Раздел для картостроителей » GUI / Jass » [СТАТЬЯ] Хеш-таблицы (Новая функция в Jass'e с патча 1.24)
[СТАТЬЯ] Хеш-таблицы
СорнемусДата: Суббота, 28 Ноябрь 2009, 02:58:29 | Сообщение # 1
9 уровень
Группа: Проверенные
Сообщений: 1187
Награды: 0
Репутация: 120
Замечания: 100%
Хеш-таблицы

Вступление

Выход нового, 1.24, патча стал проблемой для многих игроков Warcraft’а, они потеряли возможность играть в большинство нестандартных карт. Это случилось из-за фикса старой ошибки близов, называемой Return Bug, благодаря которой мы могли получить Handle любого объекта, а некоторые хакеры открыть окно cmd. Взамен они дали возможность пользоваться хеш-таблицами, которые намного удобнее и быстрее (более подробно про хеш-таблицы можно узнать на страницах Wikipedia). В данную таблицу можно записывать абсолютно любые игровые объекты или переменные. Это может быть использовано для создания оригинальных способностей юнитов или дополнительных характеристик, таких как усталость, сытость, температура и т.д. Если у вас есть хотя бы минимальные знания Jass'a, то продолжим.

Список функций

Как вы видите функций довольно много и рассказывать про каждую отдельно не имеет смысла, поэтому я расскажу лишь про основные.

Использование

Инициализация

Самой главной функцией из этого списка является функция “InitHashtable”. С помощью неё мы инициализируем хеш-таблицу для последующей работы с ней. В начале создадим глобальную переменную типа “Хеш-таблица (Hashtable)” и назовём её “Hash”, затем присвоим ей нужное значение:

Code
set udg_Hash=InitHashtable()

Получение Handle объекта

Если мы хотим присваивать объектам какие-либо значения, то нам необходим хендл данного объекта. Получить его мы можем с помощью функции “GetHandleId”. В качестве аргумента мы передаём любой игровой объект и получаем число типа “Целочисленное (integer) ”. Пример:

Code
local integer ObjectHadle
set ObjectHadle  = GetHandleId(udg_Unit)

В данном примере мы присвоили переменной “ObjectHadle” хендл юнита, заранее занесённого в переменную “udg_Unit”

Сохранение значений

Теперь когда таблица создана и мы умеем получать ссылки на объекты в неё можно записывать любые значения. Для записи используются функции с префиксом “Save” (например SaveInteger или SaveUnitHandle) из списка предоставленного выше. Простейшим примером использования данных функций является запись числа для юнита:

Code
call SaveReal(udg_Hash, GetHandleId(udg_Unit), 0, 1.00)

В первом аргументе мы передаём функции “SaveReal” хеш-таблицу (“udg_Hash”), во втором хендл юнита “udg_Unit” (созданного ранее и записанного в переменную “udg_Unit”), для которого мы хотим записать это число, в третьем “номер ячейки” данного числа(“0”), ну а четвёртым мы передали само число(“1.00”). Если мы захотим записать другие числа, то мы можем либо перезаписать его, использую функцию:

Code
call SaveReal(udg_Hash, GetHandleId(udg_Unit), 0, “2.00”)

Либо записать их в другие ячейки:

Code
call SaveReal(udg_Hash, GetHandleId(udg_Unit), 1, “3.00”)
call SaveReal(udg_Hash, GetHandleId(udg_Unit), 2, “4.00”)
call SaveReal(udg_Hash, GetHandleId(udg_Unit), 3, “5.00”)

Загрузка значений

Для загрузки из таблицы используются функции с префиксом “Load” из списка предоставленного выше. Давайте напишем функцию для загрузки числа из прошлого примера и вывода его на экран:

Code
local real test
set test=LoadReal(udg_Hash, GetHandleId(udg_Unit), 0)
call BJDebugMsg(R2S(test))

Сначала мы указываем функции хеш-таблицу (“udg_Hash”), затем даём ссылку на объект (“GetHandleId(udg_Unit)”), а в конце номер ячейки (“0”), из которой мы хотим получить это число. После выполнения этой функции переменная “Test” должна стать равной “1.00” и на экране появится соответствующая надпись

Проверка

Что бы проверить занята ли ячейки или нет пользуются функциями:

Code
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

В качестве аргументов принимаются хеш-таблица, хендл объекта и номер ячейки. Если запись в ячейке уже существует, то вернётся значение “true”, если же ячейка свободна, то функция вернёт значение “false”. Пример:

Code
if HaveSavedReal (udg_Hash, GetHandleId(udg_Unit), 0) == true then
         call BJDebugMsg(“True”)
else
         call BJDebugMsg(“False”)
endif

Удаление записи

Бывают ситуации когда необходимо удалить запись из ячейки. Например, стереть запись, содержащую какое-либо число, и записать в эту ячейку ссылку на таймер. Для этого используются функции:

Code
native  RemoveSavedInteger                    takes hashtable table, integer parentKey, integer childKey returns nothing
native  RemoveSavedReal                        takes hashtable table, integer parentKey, integer childKey returns nothing
native  RemoveSavedBoolean                    takes hashtable table, integer parentKey, integer childKey returns nothing
native  RemoveSavedString                    takes hashtable table, integer parentKey, integer childKey returns nothing
native  RemoveSavedHandle                    takes hashtable table, integer parentKey, integer childKey returns nothing

Примером очищения ячейки может служить код:

Code
call RemoveSavedReal (udg_Hash, GetHandleId(udg_Unit), 0)

Как и в прошлом примере, в качестве аргументов, мы указываем хеш-таблицу, ссылку на объект и номер ячейки.

Полное удаление записей

Последние 2 функции, которые мы с вами разберём, будут “FlushParentHashtable” и “FlushChildHashtable”. FlushParentHashtable позволяет удалить нам абсолютно все записи из хеш-таблицы. В качестве аргумента указывается только очищаемая хеш-таблица. После использования донной функции хеш-таблицу приходиться инициализировать заново! Пример:

Code
call FlushParentHashtable(udg_Hash)

А вот FlushChildHashtable нужна для удаления записей из одного объекта. Рекомендую использовать данную функцию, например при удалении юнита, так как даже есть вы удалите юнита функцией “RemoveUnit”, то его значения останутся в хеш-таблице. Пример:

Code
call FlushChildHashtable(udg_Hash, GetHandleId(udg_Unit))

Примечания

Примеры использования

Взрыв юнита

Примером использования хеш-таблиц может служить простой пример со взрывом юнита. Например мы хотим, что бы юнит взорвался после каста заклинания. Это очень просто скажите вы. Но если нужно чтобы он взорвался через 5 секунд после каста заклинания? Особо остроумные могут конечно использовать действие “Wait”, но работа с таймерами куда лучше, так как wait может повести себя абсолютно не предсказуемо, вплоть до того что действия после него просто не будут выполняться.

Code
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

Автор статьи: RazArt



Сообщение отредактировал Сорнемус - Суббота, 28 Ноябрь 2009, 03:19:32
 

GyverДата: Суббота, 28 Ноябрь 2009, 03:21:43 | Сообщение # 2
5 уровень
Группа: Пользователи
Сообщений: 108
Награды: 0
Репутация: -3
Замечания: 0%
Статья хорошая но loony её

Добавлено (28-11-2009, 03:21)
---------------------------------------------
ибо триггеры рулят :D

 

СорнемусДата: Суббота, 28 Ноябрь 2009, 03:23:06 | Сообщение # 3
9 уровень
Группа: Проверенные
Сообщений: 1187
Награды: 0
Репутация: 120
Замечания: 100%
Gyver, не советую так говорить, ибо любой джассер сейчас начнёт спор (и я в том числе).
 

ЭллесарДата: Среда, 02 Декабрь 2009, 08:15:58 | Сообщение # 4
DeMoN
Группа: Ветераны
Сообщений: 912
Награды: 1
Репутация: 121
Замечания: 0%
Самое полезное SaveInteger/LoadInteger, имхо, больше ничего и не нужно.
 

DragoNДата: Среда, 02 Декабрь 2009, 15:22:10 | Сообщение # 5
Инквизитор
Группа: Ветераны
Сообщений: 3677
Награды: 5
Репутация: 1573
Замечания: 20%
Quote (Эллесар)
Самое полезное SaveInteger/LoadInteger, имхо, больше ничего и не нужно.

для спеллов вешание хэндла юнита тоже не помешает


^ Кликабельно
Blog about everything
Похер, как ставится аккорд - главное что бы девкам доставило и посоны не загнобили. Остальное херня (с) Privitalik
 

Pa3apTДата: Среда, 02 Декабрь 2009, 16:14:55 | Сообщение # 6
8 уровень
Группа: Проверенные
Сообщений: 659
Награды: 0
Репутация: 166
Замечания: 80%
Gyver, я тебя щас loony
Эллесар, Ващет я ещё писал про call FlushChildHashtable(udg_Hash, GetHandleId(udg_Unit))
Ты сделай абилку, которая мувает объект без неё и посмотри скока раз ты её кастанёшь до лагов :)

Добавлено (02-12-2009, 16:14)
---------------------------------------------
ЗЫ А вы сам вообще чёнеть пишите или всё с хгма копипастите?


Стою я на горе
Кричу егегей.
Смотрю и вижу
А химик-то гей !
нарк
 

СорнемусДата: Среда, 02 Декабрь 2009, 16:23:23 | Сообщение # 7
9 уровень
Группа: Проверенные
Сообщений: 1187
Награды: 0
Репутация: 120
Замечания: 100%
Quote (Pa3apT)
ЗЫ А вы сам вообще чёнеть пишите или всё с хгма копипастите?

Уже пишем.
 

ЭллесарДата: Четверг, 03 Декабрь 2009, 00:49:03 | Сообщение # 8
DeMoN
Группа: Ветераны
Сообщений: 912
Награды: 1
Репутация: 121
Замечания: 0%
Quote (Pa3apT)
Эллесар, Ващет я ещё писал про call FlushChildHashtable(udg_Hash, GetHandleId(udg_Unit))
Ты сделай абилку, которая мувает объект без неё и посмотри скока раз ты её кастанёшь до лагов

Можно и без ХТ обойтись без лагов)

 

Pa3apTДата: Четверг, 03 Декабрь 2009, 14:05:59 | Сообщение # 9
8 уровень
Группа: Проверенные
Сообщений: 659
Награды: 0
Репутация: 166
Замечания: 80%
Ну можно конеч юзать массивы или ещё какой-нибудь велосипед, но зачем энто, когда есть ХТ?)

Стою я на горе
Кричу егегей.
Смотрю и вижу
А химик-то гей !
нарк
 

MaxenДата: Воскресенье, 25 Апрель 2010, 11:03:58 | Сообщение # 10
5 уровень
Группа: Проверенные
Сообщений: 137
Награды: 0
Репутация: 164
Замечания: 0%
Хм... Если будет

 

besitzeRufДата: Среда, 28 Апрель 2010, 15:55:26 | Сообщение # 11
6 уровень
Группа: Проверенные
Сообщений: 169
Награды: 0
Репутация: 5
Замечания: 0%
А можете побольше примеров с хеш таблами сделать??? ну хоть перемещение вперед скажем каждые 5 сек?

Добавлено (28-04-2010, 15:55)
---------------------------------------------
А так статья классная, она (таблица ) тебе просто облегчает всю работу...

 

QuasarДата: Суббота, 30 Октябрь 2010, 14:28:54 | Сообщение # 12
7 уровень
Группа: Проверенные
Сообщений: 330
Награды: 0
Репутация: 23
Замечания: 20%
а какова основная задача хэш таблицы?

Спелмейкер ищет работу)
 

DragoNДата: Суббота, 30 Октябрь 2010, 14:33:15 | Сообщение # 13
Инквизитор
Группа: Ветераны
Сообщений: 3677
Награды: 5
Репутация: 1573
Замечания: 20%
Quote (Сорнемус)
В данную таблицу можно записывать абсолютно любые игровые объекты или переменные. Это может быть использовано для создания оригинальных способностей юнитов или дополнительных характеристик, таких как усталость, сытость, температура и т.д. Если у вас есть хотя бы минимальные знания Jass'a, то продолжим.



^ Кликабельно
Blog about everything
Похер, как ставится аккорд - главное что бы девкам доставило и посоны не загнобили. Остальное херня (с) Privitalik
 

Banzay89Дата: Суббота, 30 Октябрь 2010, 16:33:48 | Сообщение # 14
9 уровень
Группа: Проверенные
Сообщений: 861
Награды: 1
Репутация: 53
Замечания: 20%
Запоздал автор со статьей... все кому было это интересно давным - давно уже разобрались..

 

QuasarДата: Суббота, 30 Октябрь 2010, 18:16:31 | Сообщение # 15
7 уровень
Группа: Проверенные
Сообщений: 330
Награды: 0
Репутация: 23
Замечания: 20%
Quote (Banzay89)
Запоздал автор со статьей... все кому было это интересно давным - давно уже разобрались..

а веть ношлись другие каторым это нада я например)))

Спелмейкер ищет работу)
 

Master12Дата: Воскресенье, 31 Октябрь 2010, 14:42:42 | Сообщение # 16
8 уровень
Группа: Проверенные
Сообщений: 761
Награды: 0
Репутация: 166
Замечания: 0%
полезная статейка))

Говори, что бы я тебя увидел.

 

enyaДата: Воскресенье, 07 Ноябрь 2010, 21:00:25 | Сообщение # 17
4 уровень
Группа: Проверенные
Сообщений: 86
Награды: 0
Репутация: 20
Замечания: 40%
а читал и не понел=(
 

3JIODEйДата: Суббота, 04 Декабрь 2010, 15:14:36 | Сообщение # 18
6 уровень
Группа: Заблокированные
Сообщений: 202
Награды: 0
Репутация: 47
Замечания: 20%
Статья полезна, я как раз в тупик зашел с этими мувами.

Грац меня с шестым взломом администрации
 

Pa3apTДата: Среда, 08 Декабрь 2010, 23:11:27 | Сообщение # 19
8 уровень
Группа: Проверенные
Сообщений: 659
Награды: 0
Репутация: 166
Замечания: 80%
Banzay89, статья была опубликована 27.11.2009 как раз незадолго после выхода патча
Master12, спс
3JIODEй, какими мувами?

Стою я на горе
Кричу егегей.
Смотрю и вижу
А химик-то гей !
нарк


Сообщение отредактировал Pa3apT - Среда, 08 Декабрь 2010, 23:11:35
 

BinGOДата: Четверг, 09 Декабрь 2010, 04:56:13 | Сообщение # 20
10 уровень
Группа: КоМодераторы
Сообщений: 1508
Награды: 3
Репутация: 630
Замечания: 0%
Quote (Pa3apT)
какими мувами?

Ну, наверное таймером мувать.
 

Форум о Warcraft 3 » Раздел для картостроителей » GUI / Jass » [СТАТЬЯ] Хеш-таблицы (Новая функция в Jass'e с патча 1.24)
Страница 1 из 11
Поиск:

Copyright © 2006 - 2011 Warcraft3FT.info При копировании материалов c сайта ставьте, пожалуйста, активную обратную ссылку на нас • Design by gReeB04ki ©