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

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

Ответ
 
Аминь
Crazy about that shit
offline
Опыт: 3,214
Активность:
Аттач структуры к handle
Дело в том, что я никогда не работал со структурами, и не совсем понимаю как с ними можно работать.
У меня есть система, которая может принять структуру в качестве аргумента, сохранить ее, а затем я могу считать данные из нее, когда мне будет нужно.
Пожалуйста, привидите пример такого аттача:
  1. Аттачим к хэндлу структуру, с четырьмя числами. прим. (func Save takes handle h, real r)
  2. Далее в периодическом таймере загружаем эти числа для дальнейшего использования. (func Load takes handle h returns integer)
  3. Удаляем данные, который больше не пригодятся.
Старый 03.09.2010, 11:52
AlexKARASb
Learning cpp
offline
Опыт: 22,103
Активность:
  1. Вот пример метода перебора.
» code
struct Data {
static Data array d
static timer t = CreateTimer()
static int c = 0
unit u
real a

static void Timer() {
int i = 0 
whilenot (i>=.c) { 
if .d[i].a > 0.1 { 
.d[i].u==null 
.d[i].destroy() 
.c--
.d[i] = .d[.c]
i--
if .c<= 0 {PauseTimer(.t)}}
i++ }}

static void On(unit u, real a) {
Data D = Data.create()
D.u = u
D.a = a
if .c<=0 { TimerStart(.t,0.1,true,function Data.Timer) } 
.d[.c] = D
.c++}
}
  1. Почитай jass manual
  2. еще статью Скорпа
Старый 03.09.2010, 13:38
Аминь
Crazy about that shit
offline
Опыт: 3,214
Активность:
Мануал читал, пытался разобраться. Ничего не вышло.
Статью прочитал.
Не работал со структурами и по-этому, смотрю на код, как баран на новые ворота.
AlexKARASb, можно для наглядности увидеть данный способ в действии?
Допустим прикрепить 2 инта, 2 реала на хэндл юнита, и, в периодическом таймере на 3 его запуске извлечь эти числа. Вот такой пример точно расставил бы все точки над "и".
Старый 03.09.2010, 14:05
AlexKARASb
Learning cpp
offline
Опыт: 22,103
Активность:
на хэндл юнита
Пардон, я не заметил, я тебе метод перебора, а ты спросил это ^^
Вот выкладываю свою наработку аттача через структуры, наверно и в барахолку скину для общего развития всем.
Вот карта пример.
Юнит отдает приказ смарт, перемещаясь на большой скорости к точке приказа со скоростью:
Своя скорость из РО + 400.00 от триггеров.
Все упростил для наглядности.
Еще бы хотел узнать у осведомленных:
  1. Почему у каждого юнита на карте хендл базируется на этом числе: 1040000 + 8xxx
где xxx - число различающее юнитов
  1. в коде нужно ли делать так: .d[i].destroy()
естественно желательно посмотреть код перед ответом ^^
» code
scope A initializer Init

define {
bj_map = bj_mapInitialPlayableArea
}

bool Map_check(real x,real y) { 
return (GetRectMinX(bj_map)<=x) and (x<=GetRectMaxX(bj_map)) and (GetRectMinY(bj_map)<=y) and (y<=GetRectMaxY(bj_map)) }

struct Data
    static timer t = CreateTimer() 
    static group g = CreateGroup()
    static Data array d 
    static int c = 0
    real a
    real r
    real rmax
    
static void Timer() {
    if .c>0 then 
        ForGroup(.g, lambda void() {
            unit u = GetEnumUnit()
            int i = GetHandleId(u)-1040000
            real x = GetUnitX(u)+20.00*Cos(.d[i].a)
            real y = GetUnitY(u)+20.00*Sin(.d[i].a)
            BJDebugMsg(R2S(.d[i].r))
            .d[i].r+=20.00
            if .d[i].r<.d[i].rmax and Map_check(x,y) then
                SetUnitX(u,x)
                SetUnitY(u,y)
                
            else
                BJDebugMsg(R2S(.d[i].rmax))
                PauseUnit(u,false)
                GroupRemoveUnit(.g,u)
                //.d[i].destroy() неуверен что нужно
                .c--
            endif
            u=null }) 
    else
        BJDebugMsg("timer stop")
        PauseTimer(.t)
    endif }

static void On() {
    unit u = GetTriggerUnit()
    real x = GetOrderPointX()
    real y = GetOrderPointY()
    real xu= GetUnitX(u)
    real yu= GetUnitY(u)
    int i = GetHandleId(u)-1040000
    GroupAddUnit(.g,u)
    .d[i].a = Atan2(y-yu,x-xu)
    .d[i].r = 0.00 //разница между оставшимся расстоянием и рас. до тк клика
    .d[i].rmax = SquareRoot((y-yu)*(y-yu)+(x-xu)*(x-xu))-150.00 //расстояние до точки клика
    if .c<=0 { TimerStart(.t,0.05,true,function Data.Timer) } 
    //.d[i] = D
    //BJDebugMsg(I2S(GetHandleId(u)-1040000))
    c++
    u=null}
endstruct
    
private void Init() {
    trigger t = CreateTrigger()
    TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER)
    TriggerAddCondition(t,lambda bool() { return GetIssuedOrderId()==OrderId("smart") })
    TriggerAddAction(t,function Data.On )
    t=null }
endscope
Pause false в отделе обнуления очепяточно оказалась там ^^
Прикрепленные файлы
Тип файла: w3x StructHandle.w3x (14.9 Кбайт, 27 просмотров )

Отредактировано AlexKARASb, 03.09.2010 в 16:02.
Старый 03.09.2010, 15:56
Alex_Hell
Mapmaker 'N' Programmer
offline
Опыт: 6,885
Активность:
Аминь, тебе нужно именно к любому хендлу аттачить, либо только для юнита или предмета? если 2 вариант: создавай структуру, в статических данных у которой сохранен массив всех экземпляров этой структуры, а на юнита/предмет вешай через CustomValue индекс в этом массиве
Старый 03.09.2010, 16:06
AlexKARASb
Learning cpp
offline
Опыт: 22,103
Активность:
а на юнита/предмет вешай через CustomValue индекс в этом массиве
а если этот юнит находится в другой структуре которая тоже использует его кастум валью -.-, будет сбой..
Старый 03.09.2010, 16:15
Аминь
Crazy about that shit
offline
Опыт: 3,214
Активность:
Alex_Hell, CV у меня уже используется.
Мне нужно записывать на хендл, именно инютов, данные, динамически сгенерированные перед записью в одной функции.
Я сделал это с помощью системы ToadCop'a - XAT. (сам пока до конца не понял, как это вышло)
struct spell_data {
int splid = 0
int ind = 0
float mana = 0
float cd = 0
}

void func (...) {
....
        spell_data x=spell_data.create()
        x.splid=spellid
        x.ind=AnimIndex
        x.mana=mana
        x.cd=cd
        SetDataBX(u,x)
....
}
Затем извлекаю через несколько секунд
void func2 (){
...
spell_data x=GetDataBX(u)
//Дальше считываю из стрктуры
....
RemoveDataBX(u)
x.destroy()
...
}
Я не совсем понимаю принцип работы структур и меня терзают смутные сомнения - будет ли все правильно работать в мультиплеере, при игре более одного игрока. Или же моя структура будет перезаписана при действии другого игрока, и, первый игрок получит в итоге неверные данные.
Старый 03.09.2010, 16:48
AlexKARASb
Learning cpp
offline
Опыт: 22,103
Активность:
будет ли все правильно работать в мультиплеере
Будет, принцип моего основан на принципе хешовых сохранений через хендл юнита.
Если срабатывает в хеше, то и тут будет.
Ладно я потопал. Вроде принцип своего аттача разжевал. Пойду смотреть как же Tc это сделал.
Старый 03.09.2010, 16:53
XOR

offline
Опыт: 38,159
Активность:
я когда то делал такой контейнер, может свдн помнит)
» code
library AttachLib uses main {
#define REGATTACH(TYPE) = {
handle array H##TYPE
TYPE array X##TYPE
string array Key##TYPE
int i##TYPE = 0
void attach##TYPE (handle h, TYPE x,string KEY) {
int r = 0
while(r==i##TYPE or H##TYPE[r] == h) {
if Key##TYPE[r] == KEY {
H##TYPE[r] = h
X##TYPE[r] = x
Key##TYPE[r] = KEY
else
BJDebugMsg("1")
H##TYPE[i##TYPE] = h
X##TYPE[i##TYPE] = x
Key##TYPE[i##TYPE] = KEY
}
r++
}
i##TYPE++
}
TYPE Get##TYPE(handle h,string KEY) {
int r = 0
TYPE a
while(H##TYPE[r] == h or r==i##TYPE) {
if Key##TYPE[r] == KEY {
return X##TYPE[r]
}
r++
}
debug BJDebugMsg("bad key =P")
return a
}
void Delete##TYPE(handle h,string KEY) {
int r = 0
while(H##TYPE[r] == h or r==i##TYPE) {
if Key##TYPE[r] == KEY {
H##TYPE[r] = null
i##TYPE--
debug else
debug BJDebugMsg("bad key =P")
}
r++
}
}
}
registration some attaches
REGATTACH(integer)
REGATTACH(real)
REGATTACH(string)
REGATTACH(trackable)
REGATTACH(unit)
end
}
учитывая то, что структура это инт, то
attachinteger(...)
Getinteger(...)
XimikS добавил:
делалось давно ради мультеверсионности
Старый 03.09.2010, 17:02
Аминь
Crazy about that shit
offline
Опыт: 3,214
Активность:
Дебаггер упорно выдает мне сообщение подобного рода: "Double free of type: spell_data"
Кто-нибудь сталкивался?
Что он хочет от моей структуры?
struct spell_data {
int splid = 0
int ind = 0
float mana = 0
float cd = 0
}
Старый 03.09.2010, 17:05
AlexKARASb
Learning cpp
offline
Опыт: 22,103
Активность:
Аминь, говорит тебе что спел дат уже 2. Разрешено только 1. Просит переименовать в другое название
XimikS, =\ какой не понятный синтаксис, макросы чтоль, жаль в них не шарю еще
Старый 03.09.2010, 17:19
Alex_Hell
Mapmaker 'N' Programmer
offline
Опыт: 6,885
Активность:
AlexKARASb, "а если этот юнит находится в другой структуре которая тоже использует его кастум валью -.-, будет сбой.."
Нужно делать по-уму, т.е. сделать к примеру структуру UnitData, внутри которой так же ссылки на все другие используемые структуры: Struct1, Struct2.. юниту в CustomValue писать индекс массива UnitData-структур, а от-туда получать всю нужную инфу..
при расширении системы, т.е. если нужно что-то еще вешать на юнита: в UnitData добавляем еще один параметр (ссылку на другую структуру).. никаких проблем не вижу в принципе!
К примеру:
// Первая система, где есть данные про юнита
struct MySystem1

  // Данные про юнита
  integer m_Value1
  integer m_Value2
  integer m_Value3

  // Массив экземпляров структуры
  static MySystem1 array s_MySystem1
  static integer s_MySystem1Count

endstruct

// Вторая система, где есть данные про юнита
struct MySystem2

  // Данные про юнита
  integer m_Value1
  integer m_Value2
  integer m_Value3

  // Массив экземпляров структуры
  static MySystem2 array s_MySystem2
  static integer s_MySystem2Count

endstruct

// Данные одного юнита
struct UnitData

  // Ссылки на все данные из всех структур
  MySystem1 m_MySystem1
  MySystem2 m_MySystem2

  // Массив экземпляров структуры
  static UnitData array s_UnitData
  static integer s_UnitDataCount

endstruct

// -----
// При создании юнита:
// В CustomValue сохранить индекс в массиве UnitData.s_UnitData
// Тут скорее всего потребуется совместное использование всех систем, чтобы из
// MySystem1 можно было обратиться в UnitData чтобы добавить туда ссылку на MySystem1:
// set UnitData.s_UnitData[index_1].m_MySystem1 = MySystem1.s_MySystem1[index_2]
// -----
// Когда нужно получить данные про юнита:
// Из CustomValue берем индекс к массиву UnitData.s_UnitData,
// а от туда ссылки на все остальные индексы во всех структурах

Отредактировано Alex_Hell, 03.09.2010 в 20:47.
Старый 03.09.2010, 20:36
ScorpioT1000
Работаем
offline
Опыт: отключен
делайте для каждого юнита одну главную структуру, а в ней уже сколько угодно своих кастом велью внутри :) это же элементарно
Старый 03.09.2010, 20:49
Ответ

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

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

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

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



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