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


[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Модератор форума: PUVer, SirNikolas, Ty3uK  
Проблема с ограничением кол-ва предметов
AloofДата: Вторник, 17 Июля 2012, 18:31:42 | Сообщение # 1
5 уровень
Группа: Проверенные
Сообщений: 107
Награды: 0
Репутация: 14
Блокировки:
Есть некий предмет X, который должен присутствовать у героя не более, чем в одном количестве.

Для этого я сделал 2 триггера на события EVENT_PLAYER_UNIT_SELL_ITEM и EVENT_PLAYER_UNIT_PICKUP_ITEM. Логика такая: если был куплен, то предмет уничтожается, деньги возвращаются; если был получен, то предмет падает рядом с героем. Насколько я понял, второе событие --- более общий случай, то есть оно будет срабатывать даже если предмет был куплен, причём срабатывает раньше, чем EVENT_PLAYER_UNIT_SELL_ITEM. И появилась проблема: при покупке второго предмета он падает на землю. Как избежать этого? Делать нулевой таймер?
 

ExtrematorДата: Вторник, 17 Июля 2012, 18:50:52 | Сообщение # 2
10 уровень
Группа: Проверенные
Сообщений: 3199
Награды: 0
Репутация: 1018
Блокировки:
сделай покупку пустышки...

купил "псевдо-арт"
если у героя есть уже АРТ, то... удалить псевдо-арт и дать денег
иначе, дать герою АРТ

Добавлено (17 Июля 2012, 18:50:52)
---------------------------------------------
или у тебя проблема в части подсчёта одинаковых предметов у юнита в инвентаре? хд

 

AloofДата: Вторник, 17 Июля 2012, 19:40:15 | Сообщение # 3
5 уровень
Группа: Проверенные
Сообщений: 107
Награды: 0
Репутация: 14
Блокировки:
Идея интересная, но как раз мою проблему вроде не решает, потому что проблема в срабатывании другого триггера, который выбрасывает предмет. Т.е. просто выбросит этот предмет-пустышку, ничего не изменится, по-моему.
 

SirNikolasДата: Вторник, 17 Июля 2012, 19:51:25 | Сообщение # 4
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
При дропе предмета приписываешь в хэш к нему true, запускаешь нулевой таймер. По истечении удаляешь значение из хэша.
При получении предмета (*_PICKUP_ITEM) проверяешь, если в хэше true - значит, предмет передан, если false - куплен.


 

NaturekidДата: Вторник, 17 Июля 2012, 20:10:20 | Сообщение # 5
Группа: Заблокированные
Сообщений: 4982
Награды: 3
Репутация: 3347
Блокировки:
Quote (Extremator)
если у героя есть уже АРТ, то... удалить псевдо-арт и дать денег

[тролльская придирка]
А если у героя больше 6 предметов в инвентаре и нужный предмет для проверки находится в скрытом режиме? :D
Тогда это условие не поможет, только через запоминание переменных ;)


 

ExtrematorДата: Вторник, 17 Июля 2012, 20:38:12 | Сообщение # 6
10 уровень
Группа: Проверенные
Сообщений: 3199
Награды: 0
Репутация: 1018
Блокировки:
Quote (Aloof)
Идея интересная, но как раз мою проблему вроде не решает, потому что проблема в срабатывании другого триггера, который выбрасывает предмет. Т.е. просто выбросит этот предмет-пустышку, ничего не изменится, по-моему.


иди делай как я сказал -_-

при покупке пустышки твой второй триггер не сработает, потому что ты получишь пустышку, а не сам арт

и если у героя есть арт, то арте ему не дадут
а если нету, то дадут... тогда запустится 2й триггер, который посчитает что у героя только 1 арт (который ему только что дали) и ничего не выбросит

всё
 

AloofДата: Пятница, 03 Августа 2012, 00:34:56 | Сообщение # 7
5 уровень
Группа: Проверенные
Сообщений: 107
Награды: 0
Репутация: 14
Блокировки:
Quote (SirNikolas)
При дропе предмета приписываешь в хэш к нему true, запускаешь нулевой таймер. По истечении удаляешь значение из хэша.
При получении предмета (*_PICKUP_ITEM) проверяешь, если в хэше true - значит, предмет передан, если false - куплен.

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

Да и потом: я так понял, что подобная логика основывается на том, что последовательность вызовов будет такая:

1) Обработчик события "выброс предмета" (т.е. кто-то хочется поделиться предметом), здесь запускается нулевой таймер
2) Обработчик события *_PICKUP_ITEM
3) Обработчик нулевого таймера

А есть гарантии, что вызов обработчика нулевого таймера будет именно после (2), а не после (1)? Где-то об этом можно почитать?

Quote (Extremator)
при покупке пустышки твой второй триггер не сработает, потому что ты получишь пустышку, а не сам арт

и если у героя есть арт, то арте ему не дадут
а если нету, то дадут... тогда запустится 2й триггер, который посчитает что у героя только 1 арт (который ему только что дали) и ничего не выбросит

Это несколько геморройный путь, но я тебя понял.

Добавлено (03 Августа 2012, 00:33:53)
---------------------------------------------
Блин, тут была моя ошибка.

В общем, все нормально: событие EVENT_PLAYER_UNIT_SELL_ITEM вызывается, как я и хотел --- перед событием EVENT_PLAYER_UNIT_PICKUP_ITEM. Условие для этих двух событий я сделал одинаковое, это и была ошибка. Когда юнит покупает предмет, что его еще нет в инвентаре, а когда он получил предмет, я на это не обратил внимание сначала.

Добавлено (03 Августа 2012, 00:34:56)
---------------------------------------------
Когда юнит покупает предмет, то его еще нет в инвентаре, а когда он получил предмет, то он уже есть.*

 

SirNikolasДата: Вторник, 07 Августа 2012, 13:19:18 | Сообщение # 8
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
Quote (Aloof)
А есть гарантии, что вызов обработчика нулевого таймера будет именно после (2), а не после (1)?
JASS не поддерживает многопоточность. Если один раз последовательность вызовов была такой, значит, она будет такой всегда.


 

AloofДата: Среда, 08 Августа 2012, 18:15:57 | Сообщение # 9
5 уровень
Группа: Проверенные
Сообщений: 107
Награды: 0
Репутация: 14
Блокировки:
Quote (SirNikolas)
JASS не поддерживает многопоточность

ExecFunction --- исключение?
 

HexingДата: Среда, 08 Августа 2012, 18:19:24 | Сообщение # 10
10 уровень
Группа: Проверенные
Сообщений: 1645
Награды: 1
Репутация: 432
Блокировки:
Quote (Aloof)
ExecFunction --- исключение?

+1, на хгм читал статью про написание координат курсора в игре, так там говорилось про то что в ходе игры получается много потоков, хотя читал давно, может имелись в виду потоки не связанные с jass обработкой, и вполне может быть что это присходит в 1 поток
SirNikolas, можно ли пруф?


 

SirNikolasДата: Среда, 08 Августа 2012, 18:32:54 | Сообщение # 11
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
ExecuteFunc, TriggerExecute, ForGroup, а также все функции перебора предметов и декора лишь имитируют многопоточность. На деле все выполняется последовательно.

Добавлено (08 Августа 2012, 18:32:54)
---------------------------------------------
Разница будет заметна, только если поставить TriggerSleepAction.


 

AloofДата: Среда, 08 Августа 2012, 18:41:10 | Сообщение # 12
5 уровень
Группа: Проверенные
Сообщений: 107
Награды: 0
Репутация: 14
Блокировки:
Quote (SirNikolas)
ExecuteFunc, TriggerExecute, ForGroup, а также все функции перебора предметов и декора лишь имитируют многопоточность. На деле все выполняется последовательно.

Т.е. ExecFunction() просто ставит код на выполнение в очередь, а TriggerExecute выполняет прямо тут же, прерывая выполнение текущего триггера?
 

kapa6acvlkДата: Среда, 08 Августа 2012, 18:44:02 | Сообщение # 13
Группа: Проверенные
Сообщений: 612
Награды: 0
Репутация: 361
Блокировки:
Quote (Aloof)
Т.е. ExecFunction() просто ставит код на выполнение в очередь, а TriggerExecute выполняет прямо тут же

это вряд-ли, но вызов триггера происходит быстрее, чем ExecFunction(), по крайней мере на хайве так писали во многих темах. А очередь будет и там и там.



Как говориться, не обязательно есть всю кучу говна, чтобы понять, что она однородна.
© Александр Зорич


Сообщение отредактировал kapa6acvlk - Среда, 08 Августа 2012, 18:44:22
 

SirNikolasДата: Среда, 08 Августа 2012, 18:51:19 | Сообщение # 14
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
Quote (Aloof)
а TriggerExecute выполняет прямо тут же, прерывая выполнение текущего триггера?
Они все так делают.
Если не пользоваться Sleep'ом, эти "потоки" будут выполняться в порядке стека, как обычные функции.

Добавлено (08 Августа 2012, 18:47:49)
---------------------------------------------
Code
void a() {
    printf("1")
    ExecuteFunc("b")
    printf("3")
    ExecuteFunc("c")
    printf("5")
}

void b() {
    printf("2")
    TriggerSleepAction(2.)
    printf("7")
}

void c() {
    printf("4")
    TriggerSleepAction(1.)
    printf("6")
}


Добавлено (08 Августа 2012, 18:51:19)
---------------------------------------------
Кстати, TriggerSleepAction(.0) тоже прерывает поток и, по-видимому, ставит в конец очереди исполнения, поэтому это можно использовать вместо нулевого таймера. Но из-за багнутости функции ожидания этого никто не делает.


 

AloofДата: Среда, 08 Августа 2012, 18:55:06 | Сообщение # 15
5 уровень
Группа: Проверенные
Сообщений: 107
Награды: 0
Репутация: 14
Блокировки:
SirNikolas, результат выполнения не можешь сразу тут приложить? Я тебе поверю.

Добавлено (08 Августа 2012, 18:55:06)
---------------------------------------------
Я ожидаю такого:
1
3
5
2
4
6
7

 

SirNikolasДата: Среда, 08 Августа 2012, 18:56:58 | Сообщение # 16
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:


 

AloofДата: Среда, 08 Августа 2012, 18:57:17 | Сообщение # 17
5 уровень
Группа: Проверенные
Сообщений: 107
Награды: 0
Репутация: 14
Блокировки:
Брр, или ты уже по номерам их расположил?
 

HexingДата: Среда, 08 Августа 2012, 18:57:58 | Сообщение # 18
10 уровень
Группа: Проверенные
Сообщений: 1645
Награды: 1
Репутация: 432
Блокировки:
Quote (Aloof)
Я ожидаю такого:
1
3
5
2
4
6
7

и правильно делаешь
Quote (SirNikolas)
Кстати, TriggerSleepAction(.0) тоже прерывает поток и, по-видимому, ставит в конец очереди исполнения, поэтому это можно использовать вместо нулевого таймера. Но из-за багнутости функции ожидания этого никто не делает.

а вы считаете это уместным? при использовании с нулём багов не будет?


 

SirNikolasДата: Среда, 08 Августа 2012, 19:02:00 | Сообщение # 19
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
Quote (Hexing)
при использовании с нулём багов не будет?
Проверено. Работает корректно. Для GUI-шников сойдет.
Но я все же рекомендую таймеры.




Сообщение отредактировал SirNikolas - Среда, 08 Августа 2012, 19:11:01
 

AloofДата: Среда, 08 Августа 2012, 19:02:12 | Сообщение # 20
5 уровень
Группа: Проверенные
Сообщений: 107
Награды: 0
Репутация: 14
Блокировки:
SirNikolas, OK, спасибо. Получается, никаких различий между ExecFunction("SomeFunction") и call SomeFunction() без sleep'ов нет вообще?
 

SirNikolasДата: Среда, 08 Августа 2012, 19:08:19 | Сообщение # 21
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
Есть. ExecuteFunc работает медленнее, но зато можно организовать массив строк с именами функций. А в порядке выполнения - да, вообще нет.

Добавлено (08 Августа 2012, 19:08:19)
---------------------------------------------
А, ну еще можно через Execute завязать две функции друг на друга. По строке же можно вызывать функции из любой части кода, а не только те, что сверху.


 

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

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