Сейчас 14:53:35 Четверг, 26 декабря, 2024 год
[ x ] Главная ⇒ Форум ⇐ RSS Файлы Cтатьи Картинки В о й т и   или   з а р е г и с т р и р о в а т ь с я


[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Модератор форума: PUVer, SirNikolas, Ty3uK  
[СТАТЬЯ] Хэш-таблицы
СорнемусДата: Суббота, 28 Ноября 2009, 02:58:29 | Сообщение # 1
9 уровень
Группа: Проверенные
Сообщений: 854
Награды: 0
Репутация: 120
Блокировки:
Хеш-таблицы


Вступление


Выход нового, 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) из списка предоставленного выше. Простейшим примером использования данных функций является запись числа для юнита:

[code=jass]call SaveReal(udg_Hash, GetHandleId(udg_Unit), 0, 1.00)[/code]

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

[code=jass]call SaveReal(udg_Hash, GetHandleId(udg_Unit), 0, “2.00”)[/code]

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

[code=jass]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”)[/code]


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

Для загрузки из таблицы используются функции с префиксом “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”. Пример:

[code=jass]if HaveSavedReal (udg_Hash, GetHandleId(udg_Unit), 0) == true then
call BJDebugMsg(“True”)
else
call BJDebugMsg(“False”)
endif[/code]


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

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

[code=jass]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]


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

[code=jass]call RemoveSavedReal (udg_Hash, GetHandleId(udg_Unit), 0)[/code]


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

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

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

[code=jass]call FlushParentHashtable(udg_Hash)[/code]

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

[code=jass]call FlushChildHashtable(udg_Hash, GetHandleId(udg_Unit))[/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]


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



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

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

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

 

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

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

база паролей: https://yadi.sk/d/mdDhWuvPcTSKw
бекап сайта от 26.12.2010 https://yadi.sk/d/L3xNpibbiHpYE
 

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

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


El Psy Congroo
 

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

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

 

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

Уже пишем.
 

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

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


база паролей: https://yadi.sk/d/mdDhWuvPcTSKw
бекап сайта от 26.12.2010 https://yadi.sk/d/L3xNpibbiHpYE
 

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

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

 

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

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

 

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

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

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


El Psy Congroo
 

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

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

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


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

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

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

 

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

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

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

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


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

BinGOДата: Четверг, 09 Декабря 2010, 04:56:13 | Сообщение # 20
Группа: Модераторы
Сообщений: 2906
Награды: 8
Блокировки:
Quote (Pa3apT)
какими мувами?

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

  • Страница 1 из 1
  • 1
Поиск:

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