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

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

Закрытая тема
 
DFlyer
<3 MJ
offline
Опыт: 42,879
Активность:
SCV + Array
Можно ли прикреплять к объекту переменную? В частности, массив.
Главная задача - запись/чтение большого кол-ва юнитов, которые будут записаны в массив для дальнейших действий над ними.
Какие идеи по реализации этого? Конечно можно просто тупо каждого по-очереди записать и потом по одному считывать. Может есть что-то более рациональное?
Старый 21.12.2007, 19:19
Harakternyk

offline
Опыт: 2,703
Активность:
DFlyer, хотелось бы, чтоб ты более конкретно написал в задаче о том, что именно ты с большим количеством юнитов хочешь делать...

При работе с большим количеством юнитов можно использовать массив или группу, либо и то, и другое, но и в любом случае нужно заносить в них каждого из этих юнитов поочереди, т.е.:

1) Массив:

Код:
function Add_to_array takes nothing returns nothing
    
    set udg_Many_units_array[udg_Many_units_array_Index] = GetEnumUnit()
    set udg_Many_units_array_Index = udg_Many_units_array_Index + 1

endfunction

function Set_array_content takes nothing returns nothing
    
     call ForGroupBJ( твоё условие, function Add_to_array)

endfunction


2) Группа:

Код:
function Add_to_Group  takes nothing returns nothing
    
     call GroupAddUnitSimple( GetEnumUnit(), udg_Many_units_group )

endfunction

function Set_Group_content takes nothing returns nothing
   
     call ForGroupBJ( твоё условие, function Add_to_Group )

endfunction


3) Массив и группа:

Код:
function Add_to_array_and_to_group takes nothing returns nothing
    
    set udg_Many_units_array[udg_Many_units_array_Index] = GetEnumUnit()
    set udg_Many_units_array_Index = udg_Many_units_array_Index + 1
    call GroupAddUnitSimple( GetEnumUnit(), udg_Many_units_group )

endfunction

function Set_array_and_group_content takes nothing returns nothing
    
     call ForGroupBJ( твоё условие, function Add_to_array_and_to_group)

endfunction


Замечания:

1) Последний вариант - массив с группой - расширяет состав возможных действий, которые ты можешь осуществить с юнитами этой "группы-массива". Например, можешь использовать количество юнитов в группе, для их перебора (ну, там, каждый 2-й, 3-й и т.п... + нематиматические условия "перебора", применимые к группе).

2)Можно, конечно, и cache использовать, но это от целей зависит... Повторюсь - напиши конретнее, что ты хочешь делать c большим количеством юнитов

Отредактировано Harakternyk, 21.12.2007 в 21:54.
Старый 21.12.2007, 20:37
df Hunter
Нападатель
offline
Опыт: 5,749
Активность:
саму переменную прикрепить нельзя, у вара нет функция для работы с переменными
Старый 21.12.2007, 23:21
DFlyer
<3 MJ
offline
Опыт: 42,879
Активность:
Harakternyk
Спасибо конечно за разъяснение, но ты меня не очень понял. Зри название темы. SCV.

Короче, решение пришло само собой.
Код:
// для записи массива:
loop
  call set_object_iparam(t,"unit_arr",I2S(U2I(udg_units[i]))
  exitwhen i==N
endloop

// для получеия массива:
loop
  set udg_units[i] get_object_iparam(t,"unit_arr")
  exitwhen i==N
endloop

Короче, что-то примерно так. Там уж по смыслу подогнать как надо.

Тему можно клоз.
Старый 22.12.2007, 00:25
df Hunter
Нападатель
offline
Опыт: 5,749
Активность:
ок, только ссыль на саму переменную ты никогда не получишь, у тебя здесь ссыль на обьект, записанный в данной переменной, с бесконечным циклом, еше раз подумай клоз или нет, но твой пример не рабочий, можно кэшем сделать массивы, они будут неограниченные по количеству слотов, ссыль на них можно получить, но они более медленные
Старый 22.12.2007, 01:11
Harakternyk

offline
Опыт: 2,703
Активность:
DFlyer, извини, но код этот неверный (без обид - я для пользы дела). А именно:

Цитата:
set udg_units[i] get_object_iparam(t,"unit_arr")
- выражение неправильно сформулировано. Переменная udg_units[i] должна приравниваться к юниту, а не к integer-у, т.е.:

Код:
set udg_units[i] = I2U (get_object_iparam(t,"unit_arr"))


Теперь касательно самого решения. Вызываемое значение из кеша будет отображать только последний записанный в него юнит, т.к. параметры его вызова не будут отображать его ID в памяти игры. Для того, чтоб оно получалось надо записывать:

(записывай в кешь вместе с заполнением массива)
Код:
call set_object_iparam( udg_units[i], I2S(U2I(udg_units[i]) , i)

тогда вызов будет:

Код:
set udg_units[i] = I2U ( get_object_iparam(udg_units[i], I2S ( ( U2I ( udg_units[i] ) ) ) ) )


P.S. Извини, что поправил, но я хотел просто помочь.


Harakternyk добавил:

df Hunter, да, тему пока не стоило бы закрывать...

Отредактировано Harakternyk, 22.12.2007 в 03:56.
Старый 22.12.2007, 02:20
DFlyer
<3 MJ
offline
Опыт: 42,879
Активность:
Ну, да, я ж сказал, что надо доработать. Это просто я показал основной прицнцип.

Код:
call set_object_iparam( udg_units[i], I2S(U2I(udg_units[i]) , i)

Ты прикрепляешь к переменной udg_units юнитов. Как будто переменная - это некий игровой объект. Но это нитак.


Вот, вроде, рабочий код.
Код:
...
local string array u_str
local integer i = 0
loop
  set u_str[i] = "u"+I2S(i)
  set i = i+1
  exitwhen i==udg_Size
endloop
...

// для записи в кэш:
set i = 0
loop
  call set_object_iparam(timer,I2S(U2I(udg_units[i]))+u_str[i],udg_units[i])
  set i = i+1
  exitwhen i==udg_Size
endloop
...

// для чтения из кеша
local unit array u_arr
local string array u_str
local integer i = 0

loop
  set u_str[i] = "u"+I2S(i)
  set i = i+1
  exitwhen i==udg_Size
endloop

set i = 0
loop
  set u_arr(I2U(get_object_iparam(timer,I2S(U2I(udg_units[i]))+u_str[i])
  set i = i+1
  exitwhen i==udg_Size
endloop


Т.е., создаём массив строк с именами и каждого записываем по своему адресу:
Код:
u_str0          set_object_iparam(timer,AddresFromCacheu_str0,udg_units[0])
u_str1          set_object_iparam(timer,AddresFromCacheu_str1,udg_units[1])
u_strN          set_object_iparam(timer,AddresFromCacheu_strN,udg_units[N])


Вроде ошибок нет (разве что грамматических синтаксических).

Позже обязательно проверю.

Да, тему пока не надо закрывать.

Отредактировано DFlyer, 22.12.2007 в 03:40.
Старый 22.12.2007, 03:23
Harakternyk

offline
Опыт: 2,703
Активность:
DFlyer, я и не говорил, что приклепляю массив к объекту другому, хотя ты и просил об этом - я выложил то, что позволило бы ссылаться на записанный в кешь юнит из массива.

Относительно твоего кода. На вид рабочий, но, если б ты сразу сказал, что хочешь к типу string прицепить, то другое дело было бы - каждый елемент массива строк является отдельным объектом, согласен.
Старый 22.12.2007, 03:40
DFlyer
<3 MJ
offline
Опыт: 42,879
Активность:
Ты знаешь систему SCV?

set object_iparam(object,"string1",param)
object - игровой объект (юнит, точка, и т.д.)(в частном случае мне нужен таймер)
string1 - строка, являющаяся адресом. Названием, по которому мы прикрепляем к объекту нужное нам значение param.

С get_object_iparam() тоже самое.

А ты предлагаешь прикреплять к переменной какой-то другой объект.

Ладно, имхо, мы друг-друга не понимаем.
Старый 22.12.2007, 04:07
adic3x

offline
Опыт: 108,439
Активность:
scv и cache фтопку навеки... делается вообще елементарно, если скажем колво юнитов в масиве приблизительно известно. если нет просто доработать аллокатор...

Код:
type u_g extends unit array[0x64]

...
local u_g r=u_g.create()
...
set r[0x00]=<unit_00>
set r[0x01]=<unit_01>
set r[0x02]=<unit_02>
...
call SetUnitUserData(<your_unit>, r)


для считывания
Код:
local u_g r=GetUnitUserData(<your_unit>)
local integer i=0x00

loop
 exitwhen r[i]==null
 call DoSomething(r[i])
 set i=i+0x01
endloop


правда следи за обнулением, иначе может быть попа)
Старый 22.12.2007, 11:22
exploder
iOS zealot
offline
Опыт: 19,394
Активность:
Не понял смысла кода) зачем сохранение в кэш если извлечение
Код:
set i = 0
loop
  set u_arr[i] = I2U(get_object_iparam(timer,I2S(U2I(udg_units[i]))+u_str[i]) // тут еще ошибка синтаксиса
  set i = i+1
  exitwhen i==udg_Size
endloop

эквивалентно:
Код:
set i = 0
loop
  set u_arr[i] = udg_units[i]
  set i = i+1
  exitwhen i==udg_Size
endloop

Логическая ошибка?

Что хранится в udg_units?


Код:
call SetUnitUserData(<your_unit>, r)
...
local u_g r=GetUnitUserData(<your_unit>)

Втф? type u_g == type integer?
Старый 22.12.2007, 11:31
adic3x

offline
Опыт: 108,439
Активность:
эээ, кто о чем)))
я помойму написал самый простой вариант)

ADOLF добавил:
Цитата:
type u_g == type integer?

угу) впринципе можно и написать аллакатор деструктор вручную, но там он тоже неплохо реализован) хотя я походу неписал перевод динам массивов, но там примерно тот же алгоритм, что и на структурах, вобщем зрить рыдМи)
Старый 22.12.2007, 11:36
Harakternyk

offline
Опыт: 2,703
Активность:
ADOLF, я тоже не сторонник cache-а вообще, и SCV в частности. Можно и без них многое решать более продуктивно... Классный код! Т.е. его можно использовать как integer-ссылку на юнита из массива, без RB! Надо будет поробывать реализовать это через динамический массив, т.к. со структурами я ещё не разбирался...
____________________________________________
DFlyer, не буду вдаваться в подробности по поводу того, что объектом является..., но SCV я знаю, иначе не писал бы тебе об этом. А прицепить юнита из массива к текущему (какому-то иному) значению твоего таймера можно через условия.

____________________________________________
exploder, правильно говоришь. Нет смысла в записи в cache того, что можно прочитать и без него. Да и ошибки были, но я воздержался от замечаний, ибо код на стадии разработки был...

Отредактировано Harakternyk, 22.12.2007 в 12:53.
Старый 22.12.2007, 12:05
DFlyer
<3 MJ
offline
Опыт: 42,879
Активность:
Дамн, тут я ещё ошибку допустил.
Код:
set i = 0
loop
  set u_arr[i] = I2U(get_object_iparam(timer,I2S(U2I(units[i]))+u_str[i]) // не udg_units, а просто units, локалка-массив юнитов
  set i = i+1
  exitwhen i==udg_Size
endloop


В общем, основная задача - периодическое движение юнитов. Хотел по старинке, юзая SCV прикреплять этот массив к таймеру и уже собсно двигать их.
Старый 22.12.2007, 12:47
Harakternyk

offline
Опыт: 2,703
Активность:
DFlyer, напиши как именно хочешь двигать (синхронно, хаотично, одновременно или с задержками и т.п.) - напишем код или образец дадим . Сразу бы сказал, что делать хочешь
Старый 22.12.2007, 12:51
FellGuard
Losyash
offline
Опыт: 39,547
Активность:
пффф двигать, группу цепляй
в ряде случаев EnumUnit быстрее цикла (во всяком случае с фильтром точно когда нужно сортировать)
Старый 22.12.2007, 13:19
adic3x

offline
Опыт: 108,439
Активность:
Цитата:
В общем, основная задача - периодическое движение юнитов

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

зы если что то из сказанного немного неясно спрашуй, нестесняйсо)
Старый 22.12.2007, 15:44
DFlyer
<3 MJ
offline
Опыт: 42,879
Активность:
В принципе вроде всё понятно. Проблема в том, что я с вджаззом ещё не разбирался и ни разу не работал со структурами и прочими его фишками.
Тему можно закрыть. Данная задача оказалась ненужной.
Старый 23.12.2007, 21:30
Закрытая тема

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

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

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

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



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