XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > Warcraft> Академия: форум для вопросов> Желтая пресса: обучающие статьи
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

 
RazArt

offline
Опыт: 11,197
Активность:
Хеш-таблицы

Вступление


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

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


» Функции
Код:
native  InitHashtable    takes nothing returns hashtable

native GetHandleId takes handle h returns integer

native  SaveInteger                        takes hashtable table, integer parentKey, integer childKey, integer value returns nothing
native  SaveReal                        takes hashtable table, integer parentKey, integer childKey, real value returns nothing
native  SaveBoolean                        takes hashtable table, integer parentKey, integer childKey, boolean value returns nothing
native  SaveStr                            takes hashtable table, integer parentKey, integer childKey, string value returns boolean
native  SavePlayerHandle                takes hashtable table, integer parentKey, integer childKey, player whichPlayer returns boolean
native  SaveWidgetHandle                takes hashtable table, integer parentKey, integer childKey, widget whichWidget returns boolean
native  SaveDestructableHandle            takes hashtable table, integer parentKey, integer childKey, destructable whichDestructable returns boolean
native  SaveItemHandle                    takes hashtable table, integer parentKey, integer childKey, item whichItem returns boolean
native  SaveUnitHandle                    takes hashtable table, integer parentKey, integer childKey, unit whichUnit returns boolean
native  SaveAbilityHandle                takes hashtable table, integer parentKey, integer childKey, ability whichAbility returns boolean
native  SaveTimerHandle                    takes hashtable table, integer parentKey, integer childKey, timer whichTimer returns boolean
native  SaveTriggerHandle                takes hashtable table, integer parentKey, integer childKey, trigger whichTrigger returns boolean
native  SaveTriggerConditionHandle        takes hashtable table, integer parentKey, integer childKey, triggercondition whichTriggercondition returns boolean
native  SaveTriggerActionHandle            takes hashtable table, integer parentKey, integer childKey, triggeraction whichTriggeraction returns boolean
native  SaveTriggerEventHandle            takes hashtable table, integer parentKey, integer childKey, event whichEvent returns boolean
native  SaveForceHandle                    takes hashtable table, integer parentKey, integer childKey, force whichForce returns boolean
native  SaveGroupHandle                    takes hashtable table, integer parentKey, integer childKey, group whichGroup returns boolean
native  SaveLocationHandle                takes hashtable table, integer parentKey, integer childKey, location whichLocation returns boolean
native  SaveRectHandle                    takes hashtable table, integer parentKey, integer childKey, rect whichRect returns boolean
native  SaveBooleanExprHandle            takes hashtable table, integer parentKey, integer childKey, boolexpr whichBoolexpr returns boolean
native  SaveSoundHandle                    takes hashtable table, integer parentKey, integer childKey, sound whichSound returns boolean
native  SaveEffectHandle                takes hashtable table, integer parentKey, integer childKey, effect whichEffect returns boolean
native  SaveUnitPoolHandle                takes hashtable table, integer parentKey, integer childKey, unitpool whichUnitpool returns boolean
native  SaveItemPoolHandle                takes hashtable table, integer parentKey, integer childKey, itempool whichItempool returns boolean
native  SaveQuestHandle                    takes hashtable table, integer parentKey, integer childKey, quest whichQuest returns boolean
native  SaveQuestItemHandle                takes hashtable table, integer parentKey, integer childKey, questitem whichQuestitem returns boolean
native  SaveDefeatConditionHandle        takes hashtable table, integer parentKey, integer childKey, defeatcondition whichDefeatcondition returns boolean
native  SaveTimerDialogHandle            takes hashtable table, integer parentKey, integer childKey, timerdialog whichTimerdialog returns boolean
native  SaveLeaderboardHandle            takes hashtable table, integer parentKey, integer childKey, leaderboard whichLeaderboard returns boolean
native  SaveMultiboardHandle            takes hashtable table, integer parentKey, integer childKey, multiboard whichMultiboard returns boolean
native  SaveMultiboardItemHandle        takes hashtable table, integer parentKey, integer childKey, multiboarditem whichMultiboarditem returns boolean
native  SaveTrackableHandle                takes hashtable table, integer parentKey, integer childKey, trackable whichTrackable returns boolean
native  SaveDialogHandle                takes hashtable table, integer parentKey, integer childKey, dialog whichDialog returns boolean
native  SaveButtonHandle                takes hashtable table, integer parentKey, integer childKey, button whichButton returns boolean
native  SaveTextTagHandle                takes hashtable table, integer parentKey, integer childKey, texttag whichTexttag returns boolean
native  SaveLightningHandle                takes hashtable table, integer parentKey, integer childKey, lightning whichLightning returns boolean
native  SaveImageHandle                    takes hashtable table, integer parentKey, integer childKey, image whichImage returns boolean
native  SaveUbersplatHandle                takes hashtable table, integer parentKey, integer childKey, ubersplat whichUbersplat returns boolean
native  SaveRegionHandle                takes hashtable table, integer parentKey, integer childKey, region whichRegion returns boolean
native  SaveFogStateHandle                takes hashtable table, integer parentKey, integer childKey, fogstate whichFogState returns boolean
native  SaveFogModifierHandle            takes hashtable table, integer parentKey, integer childKey, fogmodifier whichFogModifier returns boolean
native  SaveAgentHandle                    takes hashtable table, integer parentKey, integer childKey, agent whichAgent returns boolean
native  SaveHashtableHandle                takes hashtable table, integer parentKey, integer childKey, hashtable whichHashtable returns boolean

native  LoadInteger                    takes hashtable table, integer parentKey, integer childKey returns integer
native  LoadReal                    takes hashtable table, integer parentKey, integer childKey returns real
native  LoadBoolean                    takes hashtable table, integer parentKey, integer childKey returns boolean
native  LoadStr                     takes hashtable table, integer parentKey, integer childKey returns string
native  LoadPlayerHandle            takes hashtable table, integer parentKey, integer childKey returns player
native  LoadWidgetHandle            takes hashtable table, integer parentKey, integer childKey returns widget
native  LoadDestructableHandle        takes hashtable table, integer parentKey, integer childKey returns destructable
native  LoadItemHandle                takes hashtable table, integer parentKey, integer childKey returns item
native  LoadUnitHandle                takes hashtable table, integer parentKey, integer childKey returns unit
native  LoadAbilityHandle            takes hashtable table, integer parentKey, integer childKey returns ability
native  LoadTimerHandle                takes hashtable table, integer parentKey, integer childKey returns timer
native  LoadTriggerHandle            takes hashtable table, integer parentKey, integer childKey returns trigger
native  LoadTriggerConditionHandle    takes hashtable table, integer parentKey, integer childKey returns triggercondition
native  LoadTriggerActionHandle        takes hashtable table, integer parentKey, integer childKey returns triggeraction
native  LoadTriggerEventHandle        takes hashtable table, integer parentKey, integer childKey returns event
native  LoadForceHandle                takes hashtable table, integer parentKey, integer childKey returns force
native  LoadGroupHandle                takes hashtable table, integer parentKey, integer childKey returns group
native  LoadLocationHandle            takes hashtable table, integer parentKey, integer childKey returns location
native  LoadRectHandle                takes hashtable table, integer parentKey, integer childKey returns rect
native  LoadBooleanExprHandle        takes hashtable table, integer parentKey, integer childKey returns boolexpr
native  LoadSoundHandle                takes hashtable table, integer parentKey, integer childKey returns sound
native  LoadEffectHandle            takes hashtable table, integer parentKey, integer childKey returns effect
native  LoadUnitPoolHandle            takes hashtable table, integer parentKey, integer childKey returns unitpool
native  LoadItemPoolHandle            takes hashtable table, integer parentKey, integer childKey returns itempool
native  LoadQuestHandle                takes hashtable table, integer parentKey, integer childKey returns quest
native  LoadQuestItemHandle            takes hashtable table, integer parentKey, integer childKey returns questitem
native  LoadDefeatConditionHandle    takes hashtable table, integer parentKey, integer childKey returns defeatcondition
native  LoadTimerDialogHandle        takes hashtable table, integer parentKey, integer childKey returns timerdialog
native  LoadLeaderboardHandle        takes hashtable table, integer parentKey, integer childKey returns leaderboard
native  LoadMultiboardHandle        takes hashtable table, integer parentKey, integer childKey returns multiboard
native  LoadMultiboardItemHandle    takes hashtable table, integer parentKey, integer childKey returns multiboarditem
native  LoadTrackableHandle            takes hashtable table, integer parentKey, integer childKey returns trackable
native  LoadDialogHandle            takes hashtable table, integer parentKey, integer childKey returns dialog
native  LoadButtonHandle            takes hashtable table, integer parentKey, integer childKey returns button
native  LoadTextTagHandle            takes hashtable table, integer parentKey, integer childKey returns texttag
native  LoadLightningHandle            takes hashtable table, integer parentKey, integer childKey returns lightning
native  LoadImageHandle                takes hashtable table, integer parentKey, integer childKey returns image
native  LoadUbersplatHandle            takes hashtable table, integer parentKey, integer childKey returns ubersplat
native  LoadRegionHandle            takes hashtable table, integer parentKey, integer childKey returns region
native  LoadFogStateHandle            takes hashtable table, integer parentKey, integer childKey returns fogstate
native  LoadFogModifierHandle        takes hashtable table, integer parentKey, integer childKey returns fogmodifier
native  LoadHashtableHandle            takes hashtable table, integer parentKey, integer childKey returns hashtable

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

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

native  FlushParentHashtable                        takes hashtable table returns nothing
native  FlushChildHashtable                    takes hashtable table, integer parentKey returns nothing

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

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


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


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


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


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

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

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


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

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

Либо записать их в другие ячейки:
Код:
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” из списка предоставленного выше. Давайте напишем функцию для загрузки числа из прошлого примера и вывода его на экран:
Код:
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” и на экране появится соответствующая надпись

Проверка


Что бы проверить занята ли ячейки или нет пользуются функциями:
Код:
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”. Пример:
Код:
if HaveSavedReal (udg_Hash, GetHandleId(udg_Unit), 0) == true then
    call BJDebugMsg(“True”)
else
    call BJDebugMsg(“False”)
endif


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


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

Примером очищения ячейки может служить код:
Код:
call RemoveSavedReal (udg_Hash, GetHandleId(udg_Unit), 0)

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

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


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

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


Примечания



» Примечание 1

В 1 ячейке может храниться только 1 значение любого типа
Правильно:
Код:
call SaveReal(udg_Hash, GetHandleId(udg_Unit), 0, “1.00”)
call SaveUnitHandle(udg_Hash, GetHandleId(udg_Unit), 1, udg_Unit)

Не правильно:
Код:
call SaveReal(udg_Hash, GetHandleId(udg_Unit), 0, “1.00”)
call SaveUnitHandle(udg_Hash, GetHandleId(udg_Unit), 0, udg_Unit)

» Примечание 2

Рекомендую вставлять такой код в любую карту, где вы работали с хеш-таблицами, по-моему очень удобно:
Код:
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


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


Взрыв юнита


Примером использования хеш-таблиц может служить простой пример со взрывом юнита. Например мы хотим, что бы юнит взорвался после каста заклинания. Это очень просто скажите вы. Но если нужно чтобы он взорвался через 5 секунд после каста заклинания? Особо остроумные могут конечно использовать действие “Wait”, но работа с таймерами куда лучше, так как wait может повести себя абсолютно не предсказуемо, вплоть до того что действия после него просто не будут выполняться.
Код:
function Explode takes nothing returns nothing
    local timer t=GetExpiredTimer() //Получаем таймер, вызвавший данную ф-цию
    local unit u=LoadUnitHandle(udg_Hash, GetHandleId(t),1) //Загружаем нужного нам юнита

    call ExplodeUnitBJ(u) //И взрываем его :)
    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


Если вы уже не плохо знаете жасс и ранее использовали кеш, то для вас не составит труда понять как работает данный пример, ну а для новичков я сделал подсказки и пример, который вы найдёте во вложении.

Заклинания



А вот и вполне рабочие заклинания выполненные с использованием хеш-таблиц:

Blink - Автор Bee
Mana Drain - Автор Bee
Fast Run - Автор RazArt


Автор статьи – RazArt (irazart@gmail.com)

Прикрепленные файлы
Тип файла: w3x HashTable_Lesson.w3x (15.2 Кбайт, 341 просмотров )

Отредактировано RazArt, 27.11.2009 в 16:34.
Старый 18.11.2009, 22:39
Nekit1234007

offline
Опыт: 11,916
Активность:
В примере забыл call FlushChildHashtable(udg_Hash, GetHandleId(t))
Старый 18.11.2009, 22:48
RazArt

offline
Опыт: 11,197
Активность:
Ой точно fixed
Старый 18.11.2009, 22:52
Nekit1234007

offline
Опыт: 11,916
Активность:
А вообще статья труЪ. Чтоб у нубков было меньше вопросов. :)
Старый 18.11.2009, 22:57
XOR

offline
Опыт: 38,159
Активность:
Статья разжевана неплохо, но нужна только нубам имхо. Хотя.. Jassеры сами научаться, а гуишникам эти функции не к чему
Старый 18.11.2009, 23:00
RazArt

offline
Опыт: 11,197
Активность:
XiMiKs, Эм... у половины жассеров даже не было списка функций для работы с хеш таблицами :)

Та и я не думаю что с таблицами всё станет сразу ясно юзверям, которые не юзали рб и кеш...

Отредактировано RazArt, 18.11.2009 в 23:21.
Старый 18.11.2009, 23:04
bee
vjass.optimizer
offline
Опыт: 16,615
Активность:
RazArt, полезно, спасибо.
Тебя не затруднит сделать пример с локальной хеш таблицой.
Былобы очееееень полезно.
Заранее спасибо.

Отредактировано Bee, 19.11.2009 в 00:27.
Старый 19.11.2009, 00:15
Sebra

offline
Опыт: 5,603
Активность:
А зачем она нужна локально?
RazArt:
FlushParentHashtable позволяет удалить нам абсолютно все записи из хеш-таблицы. В качестве аргумента указывается только очищаемая хеш-таблица. После использования донной функции хеш-таблицу приходиться инициализировать заноВо!
Это как? Удаляет?
Старый 19.11.2009, 00:41
bee
vjass.optimizer
offline
Опыт: 16,615
Активность:
Помогите сделать MUI из моего примера.
» Library
library Hashtable initializer Init
function Angle takes real xa, real xb, real ya, real yb returns real
 return 57.295827*Atan2(yb-ya, xb-xa)
endfunction
function Explode takes nothing returns nothing
    local timer t=GetExpiredTimer() //Получаем таймер, вызвавший данную ф-цию
    local unit u=LoadUnitHandle(udg_Hash,GetHandleId(t),1) //Загружаем нужного нам юнита
    local real r=LoadReal(udg_Hash,GetHandleId(t),2)
    local real a=LoadReal(udg_Hash,GetHandleId(t),3)
    
    call BJDebugMsg("Timer Action")
    
    set r=r-0.3
    
    if r>0.00 then
    call SetUnitX(u,GetUnitX(u)+r*Cos(a*bj_DEGTORAD))
    call SetUnitY(u,GetUnitY(u)+r*Sin(a*bj_DEGTORAD))
    call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl",Get​UnitX(u),GetUnitY(u)))
    call SaveReal(udg_Hash,GetHandleId(t),2,r)
    call BJDebugMsg("move action")
    else
    call FlushChildHashtable(udg_Hash, GetHandleId(t)) //Удаляем записи таймера
    call DestroyTimer(t) //Обнуляем переменные и “разрушаем” таймер
    call BJDebugMsg("Data Flushed")
    endif
    
    set t=null
    set u=null
endfunction

function Trig_Explode_Actions takes nothing returns nothing
    local timer t=CreateTimer() //Создаём новый таймер
    local unit u=GetSpellTargetUnit() //Заносим в переменную юнита-кастера

    set udg_Hash=InitHashtable() //Инициализируем хеш-таблицу, если ранее это действие не выполнялось
    call SaveUnitHandle(udg_Hash, GetHandleId(t), 1, u) //Сохраняем ссылку на юнита “внутри” таймера
    call SaveReal(udg_Hash, GetHandleId(t), 2, 15.)
    call SaveReal(udg_Hash, GetHandleId(t), 3, Angle(GetUnitX(GetTriggerUnit()),GetUnitX(u),GetUnitY(GetTriggerUnit()),GetUnitY(u)))
    call TimerStart(t, .03, true, function Explode) //Запускаем таймер

        call BJDebugMsg("started")
    
    set t=null //Обнуляем переменные
    set u=null
endfunction

function Init 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
endlibrary
Старый 19.11.2009, 14:51
Rewenger
The culprit will not die
offline
Опыт: 35,873
Активность:
RazArt, супер. Я не пользовался хэштаблицами именно потому, что было лень выяснять, как они работают. Теперь попользуемся, пожалуй; благо появилась разжёванная статья=)
Старый 19.11.2009, 19:13
Chester
Best for you!
offline
Опыт: 5,702
Активность:
Код:
if HaveSavedReal (udg_Hash, GetHandleId(udg_Unit), 0) == true then
    call BJDebugMsg(“True”)
else
    call BJDebugMsg(“False”)
endif


Оптимальней

Код:
if HaveSavedReal (udg_Hash, GetHandleId(udg_Unit), 0) then
    call BJDebugMsg(“True”)
else
    call BJDebugMsg(“False”)
endif


Пример на cJass

Код:
if HaveSavedReal (udg_Hash, GetHandleId(udg_Unit), 0) {BJDebugMsg("true")} else {BJDebugMsg("false")}
Старый 19.11.2009, 19:19
RazArt

offline
Опыт: 11,197
Активность:
Sebra, полностью удаляет все данные и собстно саму таблицу, поэтому её приходится заново инициализировать

Bee, давай ты просто скажешь что должно происходить, а я напишу на обычном жассе?) Так как сжассы и вжассы не моё...

Отредактировано RazArt, 19.11.2009 в 20:31.
Старый 19.11.2009, 20:19
bee
vjass.optimizer
offline
Опыт: 16,615
Активность:
RazArt, я то могу сам написать на Jass / vJass / cJass
я просто хочу научится делать MUI способности на хеше.
скачай выше мой пример и переведи его на муи пожалуста.
я просто вчера пробовал у меня не получилось :| во
Старый 19.11.2009, 21:51
LostCoast

offline
Опыт: 2,633
Активность:
У меня вопрос. А что если я не буду инициализировать хеш таблицу ? вроде бы и так всё работает.... Достаточно ли того что я в иницилиз. карты это делаю?
Старый 19.11.2009, 22:47
RazArt

offline
Опыт: 11,197
Активность:
Bee, лови, я думаю ты хотел именно энто :)

LostCoast, ничего не будет вроде... Я пробовал после флуша работать с ней, ничего не получилось, инициализировал заново, всё заработало. Ну да, инициализировал 1 раз и работай с ней

2All, советую всем новичкам скачать пример и узнать как создавать муи спелы. Если что муи спелы, это те спелы, которые могут заюзать сразу 100 юнитов, а не только 1 :)
Прикрепленные файлы
Тип файла: w3x HashtableExample_RazArt.w3x (19.4 Кбайт, 149 просмотров )

Отредактировано RazArt, 19.11.2009 в 23:07.
Старый 19.11.2009, 22:49
bee
vjass.optimizer
offline
Опыт: 16,615
Активность:
RazArt, охосподи :) это же совсем другая способность и тоже не MUI
блииин, RazArt, ты меня не понял... не нужно для меня делать способность (я это и сам умею) .. мне нужно сделать способности для применения ее неограниченного кол-ва раз. я не знаю как это делается и поэтому спрашиваю. там в функции Actions должна создаваться каждое применение новая хеш таблица... т.е. смотри наприме я кастанул способность на воина, он передвигается, передвигается, и вдруг какойто другой воин тоже применяет такуеже способность. срабатывает одна и таже функция и хеш данные об передвигаемом воине перезаписываются. и у тебя не MUI спелл :) ты наверное не тот пример выложил))
Bee добавил:
ты просто добавил отталкивание от преград :)
но это всеравно не MUI )
Старый 19.11.2009, 23:29
RazArt

offline
Опыт: 11,197
Активность:
Bee
1) Юзать её можно сразу 5 юнитами на 1, будет всё норм работать, энто как раз таки муи
2) Не нужно для каждого каста создавать новую хеш-таблицу, потому что энто бред...

Отредактировано RazArt, 19.11.2009 в 23:41.
Старый 19.11.2009, 23:34
bee
vjass.optimizer
offline
Опыт: 16,615
Активность:
RazArt, скачай пример который ты выложил и проверь еще раз.
Не нужно для каждого каста создавать новую хеш-таблицу, потому что энто бред...
видел 2-3 такие способности - они отлично работали, только я немогу их найти :D
Старый 19.11.2009, 23:40
Killer574
Временно присутствующий.
offline
Опыт: 3,373
Активность:
Bee, не скачивал пример, но что-то в твоем коде мне подсказывает, что стоит просто стереть строку
set udg_Hash=InitHashtable()
инициализацию нужно делать только 1 раз имхо например в триггере инициализации :D
Старый 19.11.2009, 23:41
RazArt

offline
Опыт: 11,197
Активность:
Я проверял, всё норм. Можно конечно ещё в юнита записать таймер и если прошлый не завершался дестрюкать его, но зачем...

Выглядит примерно так:
» раскрыть
Код:
function Trig_Explode_Actions takes nothing returns nothing
    local timer t=CreateTimer()
    local unit cu=GetTriggerUnit()
    local unit stu=GetSpellTargetUnit()
    local location up=GetUnitLoc(cu)
    local location sp=GetUnitLoc(stu)
    local real speed=20.0
    local real angle=AngleBetweenPoints(up, sp)

    set udg_Hash=InitHashtable()
    //---
    if LoadReal(udg_Hash,GetHandleId(LoadTimerHandle(udg_Hash, GetHandleId(stu), 0)),4)>0 then //Если прошлый таймер действует на юнита
        call FlushChildHashtable(udg_Hash, GetHandleId(LoadTimerHandle(udg_Hash, GetHandleId(cu), 0)))
        call DestroyTimer(LoadTimerHandle(udg_Hash, GetHandleId(cu), 0)) //то разрушаем его
    endif
    call SaveTimerHandle(udg_Hash, GetHandleId(stu), 0, t) //Перезаписываем прошлый таймер
    //---
    call SaveUnitHandle(udg_Hash, GetHandleId(t), 0, cu)
    call SaveUnitHandle(udg_Hash, GetHandleId(t), 1, stu)
    call SaveLocationHandle(udg_Hash, GetHandleId(t), 2, up)
    call SaveLocationHandle(udg_Hash, GetHandleId(t), 3, sp)
    call SaveReal(udg_Hash, GetHandleId(t), 4, speed)
    call SaveReal(udg_Hash, GetHandleId(t), 5, angle)

    call SetUnitPathing( stu, false )
    call TimerStart(t, 0.03, true, function Move_Unit)

    set t=null
    set cu=null
    set stu=null
    call RemoveLocation(up)
    call RemoveLocation(sp)
    set up=null
    set sp=null
endfunction

Кста предыдущий оратор был прав :)

Отредактировано RazArt, 19.11.2009 в 23:56.
Старый 19.11.2009, 23:42

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы можете скачивать файлы

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 11:24.