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

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

Ответ
 
Sergey
Старейший
offline
Опыт: 44,363
Активность:
Новая версия NCV
Спасибо Димону, что навел на эту идею. NCV переделан с использованием кеша. За счет этого количество переменных удалось снизить до одной (притом, что в кеш можно писать хоть до бесконечности), но для тех, кто плохо знаком с jass наработка стала пожалуй даже тяжелее прежней. Но что делать...
Короче вот сценарий.
Прикрепленные файлы
Тип файла: w3x NCV.w3x (20.5 Кбайт, 101 просмотров )
Старый 13.02.2005, 16:36
Sergey
Старейший
offline
Опыт: 44,363
Активность:
NVC - это система New Custom Value. В варике есть возможность делать сопостовления переменных юниту. Точнее в варике каждому юниту можно сопоставить число типа integer. Это хорошо, но число только одно. А иногда (да что уж там - довольно часто, когда к работаешь к примеру над созданием триггерных заклинаний). Возникает необходимость оспоставить юниту более одного числа. Или скажем не число, а спецэффект, другой юнит и т.п. Моя система успешно решает такие задачи, поскольку сопостовлять юниту можно что угодно и в любых количествах.
Старый 13.02.2005, 19:48
zibada

offline
Опыт: отключен
сергей, на самом деле, все делается намного проще =)) думал небольшую статейку на данную тему написать, да все руки не дойдут...

так вот, суть в том, что с помощью кэша любому объекту, будь то юнит, триггер, спецэффект или что бы то ни было еще, можно сделать сколько угодно параметров любого типа.
как известно, для доступа к отдельным элементам кэша используются 2 строки - ключ миссии, и ключ, собственно, элемента.
так вот, основная идея (придуманная еще буржуями давным-давно, но почему-то не получившая у нас распространения) заключается в том, чтобы в качестве первого из ключей использовать handle объекта - уникальный номер каждого объекта на карте, преобразованный в строчку. тогда в качестве 2-го ключа можно использовать произвольную строку - и перекрытия с другими объектами никогда не произойдет.

реализуется это все несколькими функциями, в одну-две строчки каждая:
Код:
function H2I takes handle h returns integer
return h
return 0
endfunction

function get_object_iparam takes handle h, string key returns integer
   return GetStoredInteger(udg_cache, I2S(H2I(h)), key)
endfunction

function set_object_iparam takes handle h, string key, integer val returns nothing
   call StoreInteger(udg_cache, I2S(H2I(h)), key, val)
endfunction

function get_object_rparam takes handle h, string key returns real
   return GetStoredReal(udg_cache, I2S(H2I(h)), key)
endfunction

function set_object_rparam takes handle h, string key, real val returns nothing
   call StoreReal(udg_cache, I2S(H2I(h)), key, val)
endfunction

function flush_object takes handle h returns nothing
   call FlushStoredMission(udg_cache, I2S(H2I(h)))
endfunction

(потребуется в редакторе создать переменную "cache" типа Game Cache)

у меня сделано сохранение только целых и вещественных значений, строки можно приделать аналогично. все ссылочные типы можно сохранить как целые, применив к ним функцию H2I.

после чего можно в любом месте кода можно писать что-то вида:
call set_object_iparam(u, "lives", 100)
таким образом, одному конкретному юниту установится параметр, названный нами "lives" (название выбирается произвольно! никаких номеров запоминать не надо) со значением в 100.

чтобы получить где-либо доступ к сохраненному значению, достаточно, опять-таки, лишь ссылки на юнита:
get_object_iparam(u, "lives")

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

в общем, краткая суть вот... у меня полностью на этом принципе "тюлень" и сделан. :)

Отредактировано DimonT, 13.02.2005 в 20:02.
Старый 13.02.2005, 19:53
Sergey
Старейший
offline
Опыт: 44,363
Активность:
Димон, опять же спасибо. Я как раз столкнулся с тем, что не очень приятно создавать для всего отдельную функцию и хотел спросить, можно ли использовать какой-то универсальный тип =). Чтож, сейчас подправлю. Ждите.

Sergey добавил:
Димон, только объясни действие команды "call FlushStoredMission". Т.е. в целом я понял, но хочется подробнее.

Sergey добавил:
Хм... Похоже незачем изобретать велосипед =). Димон, круто. Это уже не NCV, а SCV - SUPER custom value =).
Старый 13.02.2005, 20:42
zibada

offline
Опыт: отключен
куда тут подробнее-то..
FlushStoredMission удаляет из кэша все записи с указанным "ключом миссии" (1-м из пары). ну допустим, мы удаляем юнита - зачем же дальше держать в памяти все его "дополнительные custom value", когда доступ к ним мы все равно получить больше не сможем?
Старый 13.02.2005, 20:46
Sergey
Старейший
offline
Опыт: 44,363
Активность:
От черт побери, просто и изящно! Настоящий мастер. И все же, Димон если ты не против, я немного улучшу твою работу в том плане, чтобы записывать в SCV можно было не только integer и real, но и boolean, строки, юниты, предметы и спецэффекты. Джентельменский набор для триггерных заклинаний =).
Старый 13.02.2005, 20:51
zibada

offline
Опыт: отключен
еще одна, не самая очевидная, но весьма мощная идея заключается в том, чтобы крепить параметры к... периодически срабатывающим триггерам.
допустим, у нас триггерный спелл устроен так, что N раз в секунду он что-то с юнитом делает. удобно создать отдельный периодический триггер, выполняющий это самое действие, но есть проблема: триггер должен как-то "узнавать", с каким же юнитом ему работать.
локальные переменные не годятся, т.к. их значения от срабатывания к срабатыванию не переносятся. хранить в глобальных - неудобно, когда несколько юнитов могут юзнуть наш спелл одновременно.
а вот с кэшем проблема решается более чем изящно: мы прямо в свойства триггера при его создании указанным выше методом пропишем ссылку на юнита, с которым он должен работать.
так как номер у каждого нового триггера свой, и он НЕ меняется от запуска к запуску, каждому триггеру мы можем навесить сколько угодно таких своеобразных "локальных" переменных, которые будут не видны из другого триггера, и в то же время - будут переноситься.
для триггерных заклинаний это бесценно - пример реализации этого хозяйства, я думаю, вы все видели.
хм.. уже и статью писать незачем - все рассказал =)
Старый 13.02.2005, 21:00
Sergey
Старейший
offline
Опыт: 44,363
Активность:
Тоник, идея может и не плоха, но я не в курсе - возможно (даже наверняка) у буржуев уже есть аналоги (т.к. с уровнем заклинаний, которые они создают, это неизбежно). Тем более, что буржуи еще раньше нашего связались с записью в кеш и типом handle.
Поражает, что система по вышла настолько простой... Там и кода меньше чем на экран.
Старый 13.02.2005, 21:02
zibada

offline
Опыт: отключен
сергей, чтобы записать в кэш ссылку, например, на юнита, отдельных функций не нужно - достаточно написать что-то вроде:
call set_object_iparam(u, "unit1", H2I(udg_MyUnit))

а вот чтобы получить обратно из сохраненного значения юнита, придется все же добавить 1 функцию:
Код:
function I2U takes integer i returns unit
return i
return null
endfunction

и так по 1 функции для каждого типа, для которого нужно обратное преобразование... для прямого преобразования новых функций не надо - H2I универсальна.
Старый 13.02.2005, 21:05
Sergey
Старейший
offline
Опыт: 44,363
Активность:
Да, я уже понял. Ну короче доделываю систему, сделаю пример, краткое описание и вышлю сюда для окончательной правки.
Старый 13.02.2005, 21:12
Markiz

offline
Опыт: 11,432
Активность:
Все гениальное просто, что нам и доказывает существование SCV, для которого нужны лишь функций длиною в одну строку =)
Старый 13.02.2005, 22:45
Sergey
Старейший
offline
Опыт: 44,363
Активность:
Итак, финальная версия. Дело за Димоном - проверить, распространить и может быть написать статью. Всем jass-ерам рекоменую ознакомиться.
Прикрепленные файлы
Тип файла: w3x SCV.w3x (25.1 Кбайт, 85 просмотров )

Отредактировано Sergey, 14.02.2005 в 08:41.
Старый 13.02.2005, 23:53
zibada

offline
Опыт: отключен
ценим cтатью =)
http://xgm.guru/wc3/articles.php?do=showart&artid=102

сергей, эту твою систему я туда приложил как один из примеров...
Старый 15.02.2005, 09:08
Sergey
Старейший
offline
Опыт: 44,363
Активность:
Класс, мне нравится. Можно кстати найти твоей системе еще одно применение. Мы ведь не обязаны делать записи в кеш, сопоставляя их какому-то объекту. Если не делать сопостовления, то мы получаем... Стандарные переменные! Причем эти переменные можно создавать прямо по ходу игры и давать им любое название. Можно создавать даже массивы.

Хорошо бы модернизировать пример и скрипты, чтобы продемонстрировать эту возможность.

Sergey добавил:
С одной стороны, наверное можно использовать объект null, чтобы писать значения переменных. Только предупредить, чтобы названия CV не совпадали с названиями доп. переменных. Мало ли что может быть... Бывает и так, что применяешь функцию к объекту, которого не существует. Тогда будет сюой со значением.

С другой стороны, существующая система пока не позволяет сопостовлять МАССИВЫ. Это упущение хорошо бы исправить. И сделать это, кстати говоря, не так уж сложно. Только ввести еще один параметр в функции, отвечающий за индекс элемента.
Старый 15.02.2005, 12:29
Sergey
Старейший
offline
Опыт: 44,363
Активность:
Димон, короче вот. Дополнил пример кратким руководством, как создавать массивы и переменные. Думаю, что стоит обновить пример на сайте.
Прикрепленные файлы
Тип файла: w3x SCV.w3x (26.7 Кбайт, 98 просмотров )

Отредактировано Sergey, 15.02.2005 в 18:45.
Старый 15.02.2005, 18:39
Ответ

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

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

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

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



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