27

» WarCraft 3 / Угол поворота

Принятый ответ
вот 2, 3, 4 варианты точно подойдут
прочитай второй вариант почему это происходит. Тоже делал как ты.
27

» WarCraft 3 / Возможно оследить какое здание тренирует юнитов!!

Принятый ответ
возможно дебагом
но для разъяснения стоит посмотреть тут
при событии юнит начинает подготовку тренируемого юнита нет, но можно выявить его тип id с помощью trained unit-type.
Загруженные файлы
27

» WarCraft 3 / Как убрать появляющийся мультибоард при ливе игроков?

Принятый ответ
Переписать стандартные триггеры. Вы используете стандартные гуишные триггеры? Если да, то надо раскрыть и посмотреть. Кажется из-за них вызывает ошибку.
раскрыть
MeleeStartingVisibility - настраивает игровое время (часики)
MeleeStartingHeroLimit - устанавливает лимит на каждого героя (каждый игрок может призвать 1 тип героя) и каждый игрок может призвать максимум 3 героя
MeleeGrantHeroItems - настройки кол-ва героев. регистрирует кол-во героев при обучении или покупке в нейтральном магазине. Короче стартовое ограничение, зависит от технического прогресса базы ( на первом уровне = максимум 1 герой, на втором = максимум 2 героев, на третьем = максимум 3 героя). Тут фиксируется нанятое кол-во героев игроком (нанял или купил +1, нанял еще одного +2, нанял третьего +3, максимум можно 3).
MeleeStartingResources - стартовые ресурсы игрока
MeleeClearExcessUnits - очищает место от нейтральных крипов, чтобы на этой местности расставить рабов и ратушу. Обычно место выбирается "исходной позицией".
MeleeStartingUnits - создает ратушу и рабов
MeleeStartingAI - проверяет всех игроков (кем заняты слоты: игроком или компьютером, если комп, то включает ИИ)
MeleeInitVictoryDefeat - настройки условия поражения. Отвечает за условия изменения альянса, за выход (лив) игрока из игры, Тут намного больше кода чем в остальных частях. Именно здесь нужно искать.
непонятный близзардский говнокод функции MeleeInitVictoryDefeat
function MeleeInitVictoryDefeat takes nothing returns nothing
    local trigger    trig
    local integer    index
    local player     indexPlayer

    // Создаем в начале игры окно таймера для тайм-аута «закончить в ближайшее время», у него пока что нет таймера
    // потому что он управляется в реальном времени (вне состояния игры, чтобы избежать desyncs)
    // Это окно появляется, если у игрока разрушена база (в частности ратушена уничтожена), и появляется окно, оповещающее что если не построите здание, то вы проиграете. Так думаю я. Мб и в других ситуациях, но что-то не припомню где еще диалоговое окно с таймером появлялось
    set bj_finishSoonTimerDialog = CreateTimerDialog(null)

    // Установите триггер для запуска, когда мы получим игровое событие «закончить в ближайшее время»
   //не понятно мне что это
    set trig = CreateTrigger()
    call TriggerRegisterGameEvent(trig, EVENT_GAME_TOURNAMENT_FINISH_SOON)
    call TriggerAddAction(trig, function MeleeTriggerTournamentFinishSoon)

    // Установите триггер для запуска, когда мы получим игровое событие «закончить сейчас»
   //не понятно мне это тоже 
    set trig = CreateTrigger()
    call TriggerRegisterGameEvent(trig, EVENT_GAME_TOURNAMENT_FINISH_NOW)
    call TriggerAddAction(trig, function MeleeTriggerTournamentFinishNow)

    // Настройка поражения для каждого игрока (перебираем циклом каждого игрока)
    set index = 0
    loop
        set indexPlayer = Player(index)

        //Если этот игрок имеет статус "играет" (указан в слоте).
        if (GetPlayerSlotState(indexPlayer) == PLAYER_SLOT_STATE_PLAYING) then
            set bj_meleeDefeated[index] = false
            set bj_meleeVictoried[index] = false

            //Создаем окно таймера и таймер
            set bj_playerIsCrippled[index] = false
            set bj_playerIsExposed[index] = false
            set bj_crippledTimer[index] = CreateTimer()
            set bj_crippledTimerWindows[index] = CreateTimerDialog(bj_crippledTimer[index])
            call TimerDialogSetTitle(bj_crippledTimerWindows[index], MeleeGetCrippledTimerMessage(indexPlayer))

            // Запускаем триггер, когда здание отменяется (прерывается через кнопку отмена) для этого игрока. 
            // Короче можно сделать счетчик на кол-во здании у каждого игрока. Если отменяет значит -1
            set trig = CreateTrigger()
            call TriggerRegisterPlayerUnitEvent(trig, indexPlayer, EVENT_PLAYER_UNIT_CONSTRUCT_CANCEL, null)
            call TriggerAddAction(trig, function MeleeTriggerActionConstructCancel) //вот в действии много чего намусолено

            // Устанавливаем триггер для срабатывания всякий раз, когда здание умирает у этого игрока.
            // Короче можно сделать счетчик на кол-во здании у каждого игрока. Если умирает значит -1
            set trig = CreateTrigger()
            call TriggerRegisterPlayerUnitEvent(trig, indexPlayer, EVENT_PLAYER_UNIT_DEATH, null)
            call TriggerAddAction(trig, function MeleeTriggerActionUnitDeath) //вот в действии много чего намусолено

            // Устанавливаем триггер для срабатывания всякий раз, когда устройство начинает строительство для этого игрока
            // Короче можно сделать счетчик на кол-во здании у каждого игрока. Если завершает значит +1
            set trig = CreateTrigger()
            call TriggerRegisterPlayerUnitEvent(trig, indexPlayer, EVENT_PLAYER_UNIT_CONSTRUCT_START, null)
            call TriggerAddAction(trig, function MeleeTriggerActionUnitConstructionStart) //вот в действии много чего

            // Установите триггер, который будет срабатывать, когда игрок проиграет
            set trig = CreateTrigger()
            call TriggerRegisterPlayerEvent(trig, indexPlayer, EVENT_PLAYER_DEFEAT)
            call TriggerAddAction(trig, function MeleeTriggerActionPlayerDefeated)

            // Устанавливаем триггер, когда он уходит из игры
            set trig = CreateTrigger()
            call TriggerRegisterPlayerEvent(trig, indexPlayer, EVENT_PLAYER_LEAVE)
            call TriggerAddAction(trig, function MeleeTriggerActionPlayerLeft)

            // Установите триггер, чтобы он срабатывал всякий раз, когда этот игрок меняет свои союзы.
            set trig = CreateTrigger()
            call TriggerRegisterPlayerAllianceChange(trig, indexPlayer, ALLIANCE_PASSIVE)
            call TriggerRegisterPlayerStateEvent(trig, indexPlayer, PLAYER_STATE_ALLIED_VICTORY, EQUAL, 1)
            call TriggerAddAction(trig, function MeleeTriggerActionAllianceChange)
        else

	    //Иначе, если игрок "не играет" скорее всего наблюдатели игры

            set bj_meleeDefeated[index] = true
            set bj_meleeVictoried[index] = false

            // Обработка событий для наблюдателей
            if (IsPlayerObserver(indexPlayer)) then
                // Устанавливаем триггер, когда он уходит из игры
                set trig = CreateTrigger()
                call TriggerRegisterPlayerEvent(trig, indexPlayer, EVENT_PLAYER_LEAVE)
                call TriggerAddAction(trig, function MeleeTriggerActionPlayerLeft)
            endif
        endif

        set index = index + 1
        exitwhen index == bj_MAX_PLAYERS
    endloop
    
    //Запускаем таймер. Через 2 секунды запускаем тестовую проверку.
    //Тест на победу/поражение при запуске, если пользователь уже выиграл / проиграл. 
    //Просто проверяем играет ли пользователь один, например, если да, то можно вручить ему победу. 
    // Разрешить короткое время, чтобы пройти первым, чтобы карта могла завершить загрузку.
    //Короче проверяем есть ли построенные здания типа ратуши.
    call TimerStart(CreateTimer(), 2.0, false, function MeleeTriggerActionAllianceChange)
endfunction
Лично больше всего не понятно именно эта часть. Как связано и другое. Я бы переписал бы по-другому.
покопался в MeleeInitVictoryDefeat и не обнаружил никакого мультиборда =((
видимо встроен извнутри
знаешь мультибордов можно создать 10-20. Но отобразить игроку можешь только один. Поэтому когда появляется этот мультиборд, покажи снова свой. Единственное, что жаль нельзя удалить этот появившийся мультиборд, ссылки то на него нет. Попробуй последний созданный удалить что ль. Не знаю баг или не баг, а это связано ли с режимом сражения? попробуй отключить MeleeInitVictoryDefeat и проверить без него как работает, просто в этой функции очень много чего напихано, возможно какой-то элемент включает (переменная какая-нибудь)
Еще если союзник ливает, то делай его врагом. И его войска отдаешь себе и все.
27

» WarCraft 3 / Почему нельзя создать больше TriggerAddCondition для 1 триггера?

не понятно, что не работает и что вы хотите сделать.
не знаю мб поможет
Можно использовать нативку
GetTriggerEventId() - возвращает событие
GetHandleId(GetTriggerEventId()) - возвращает номер события
например событие юнит использует событие EVENT_PLAYER_UNIT_ISSUED_ORDER
constant playerunitevent EVENT_PLAYER_UNIT_ISSUED_ORDER=ConvertPlayerUnitEvent(38)
возвращает число 38
constant playerunitevent EVENT_PLAYER_UNIT_USE_ITEM=ConvertPlayerUnitEvent(50)
возвращает число 50
constant playerunitevent EVENT_PLAYER_UNIT_SPELL_CAST=ConvertPlayerUnitEvent(273)
возвращает число 273
тогда можно несколько событии на один триггер, если в вашем случае поможет. Не знаю, что вы хотите сделать.
27

» WarCraft 3 / События это не проблема?

Принятый ответ
объяснение
если герой удалил с помощью репик героя
Не понял что ты написал, если имеешь в виду удалить героя (RemoveUnit), то это событие никогда не запустит поток, так как объекта то уже нет (удален). Не должно по идее. Во-вторых, нельзя удалить событие. Событие обычно вешают (регистрируют) на объекты (юниты, игроки и др), большая часть стандартных событии (юнит умирает, юнит применяет абилу и др короче общие события) - вешают (регистрируют) на игроков. Короче событие - рычаг, который фиксирует изменения объекта. Есть другие еще событие со временем - "запускать каждые ... секунд" - тоже рычаг, но переменных не дает (типа Dying Unit(), GetTriggerUnit() и др)
Если смотреть по поводу того утечек и как лучше сделать/оптимизировать случаи с единичными событиями, которые вешают на одного юнита:
  1. есть два варианта либо вешаешь все на один триггер события разных юнитов (еще нужно в некоторых случаях запихивать юнитов в группу для проверки, если там такой юнит есть, то не нужно добавлять) и не париться (рабочий вариант). Пример_GUI_Impetus,
  2. Или создаешь каждый раз новый триггер, регистрируешь на него событие юнита (пример при атаке), (так было сделано в доте, видимо для успешной атаки, типа отслеживаешь что это был физический удар, скилл Impetus), потом ссылки на action и condition запоминаешь в переменные или в хэшз, затем удаляешь условие/действие, и триггер удалить. Условие можно не удалять, кто-то писал что не нужно
Можно привести к моему выводу, что событие не удалить. Тестировал давно функции ссылка на игроках, Рисую ситуацию: на игрока зарегистрировал событие (применить скилл), прикрепил также к триггеру условие и действие.
Игрок запускает способность => срабатывает событие => проходит проверка условия => действие.
Если убрать действие или условие, то рычаг все равно работает. Отсюда следует вывод: даже будь хоть выключен триггер, событие все равно работает. Функция GetTriggerEvalCount - этой функции можно проверить сколько раз запускал условие с событием. Но как-то пробовал еще и без условия проверить, прокатывает и на событие походу (точнее это счетчик на событие). Так как рычагом является игрок. А если рычагом станет не игрок, а юнит (часто систему урона на него вешают), то там юнита можно удалить, и событие никогда не заработает, так как его уже нет
Что хочу сказать. Если у тебя 50 триггерных скилов, и 50 триггеров с одним и тем же событием, лучше его оптимизировать, на одно событие. Где-то была ссылка
это будет надеюсь понятно
27

» WarCraft 3 / Аттачменты у способностей

Сфера 'Asph' - пустышка с невидимой иконкой можно использовать в качестве аттача моделей на юнита (если они указаны в моделе юнита). Это связано с моделью Келя
  1. В ней можно указать куда хотели бы нацепить модель: на руку (на правую или левую), плечо, грудь, голову или нацепить и отобразить эффект-модель под ногами героя. Самое простое - использовать модель оружия (меча). Если хотите, чтобы он оказался в руке (в большинстве случае это будет выглядеть глупо, так как от руки меч может парить в воздухе, нужно чтобы соответствовала модель, которую хотите нацепить, с моделью юнита).
Воздействие на цель 1-6: Здесь вручную прописываются области тела применившего заклинание, в которых будут специальные эффекты, указанные в пункте "Графика – цель". Каждую область тела нужно прописывать в разных пунктах – т.о. у нас есть возможность прикрепить эффект к шести точкам тела воина, применившего заклинание.
Возможные варианты:
hand,right – правая рука.
hand,left – левая рука.
origin – стандартное положение, прописанное в свойствах эффекта. Объясню: например, "Доспехи веры" – графический эффект этой модели появляется у ног героя, а у "Проклятия" - над головой.
head – над головой (изменяется вместе с анимацией).
chest – грудная клетка.
foot,left – левая нога.
foot,right – правая нога.
overhead – над воином ( не изменяется вместе с анимацией).
weapon,left, weapon,right – на оружие в левой и в правой руке героя соответственно.
mount – поверхность. Можно использовать так: chest,mount,left и т.д. Вы помните способность "Выставить шипы" для Анубарака.
Преимущество от этого большое, дело в том, что не во всех способностях так легко нацепить какую-нибудь модель. Про спецэффекты не в счет.
  1. Модель также отображает анимацию. Допустим, смотрим у героя Келя есть эта пустышка. Вокруг этого героя кружится огненный шар, это анимация модели. Отвечает за это sprite
sprite – для отображения эффектов на юнитов. У каждого юнита, точнее сказать модели юнита свои точки прикрепления. Если взять модель не Келя, а например, эльфийской лучницы, то у нее не отобразятся эти эффекты движения шаров, что есть у Келя. Прописывать нужно в "воздействие на цель 1-6". Примеры: Sprite,first; sprite,second; sprite,third; sprite,fourth; sprite,fifth; sprite,sixth.
у модели Келя анимация движения шаров расчитано на три шара (то есть Sprite,first; sprite,second; sprite,third). Дальше бесполезно прописывать, так как не рассчитано в модели видимо. В доте анимировано движение четырех шаров, видимо там другая модель.
  1. Указываем модель. в пункте "Графика – цель" указываем модель, в этом пункте имеются анимации/эффекты для различных частей тела, этот эффект успешно отобразится на соответствующих частях тела кастера.
  1. Указываем кол-во точек крепления. Задать сценарий воздействия: указываем количество прикрепляемых эффектов к юниту-кастеру. Например, мы заполнили все шесть параметров "воздействие на цель". Ставим в данном пункте цифру 6. Затем, в поле "Графика – цель" указываем шесть различных эффектов анимации, которые будут прикреплены к юниту-кастеру соответственно к тем местам, которые указаны в пунктах "воздействие на цель" с 1 по 6.
  1. Способность Келя очень специфична. Я долго не догадывался и не обращал внимание, о том, что шар исчезает после атаки. И с каждой новой атакой пропадает еще один. Это заметить трудно, дело в том, что шар заново появлялся и кружился. Думал, что это так визуально подстроено в моделе юнита (там часто у юнитов что-то сверкает, кружится - короче анимация атак). Если перезарядку скила поставить побольше и дать Келю пострелять во врагов, будет заметно, что с каждым разом шаров становится все меньше, пока совсем не исчезнет.
ACnr (Аура восстановления здоровья) - это взято из проводника
Идеальная способность для прикрепления боевым единицам эффектов с сохранением цвета команды. Просто установите нулевое значение в поле “Данные – Объем восстановленного здоровья” и значение “Сам воин” в поле “Характеристики – Разрешенные цели”. Затем задайте модель, которую Вам нужно прикрепить (“Графика - Цель”), а в поле “Графика – Воздействие на цель 1” впишите названия соответствующих точек прикрепления.
Вот эти точки:
overhead – над головой
head – голова
chest – за спиной
origin – туловище
hand – рука
foot –нога
weapon – оружие (только для героев)
sprite – для зданий
medium – для зданий
large – для зданий
К точке прикрепления можно добавить модификаторы:
left – лево
right – право
mount – для обездвиженных боевых единиц
rear – для четвероногих
first – первый (для зданий)
second – второй (для зданий)
third – третий (для зданий)
fourth – четвертый (для зданий)
fifth – пятый (для зданий)
sixth – шестой (для зданий)
rallypoint – для зданий
Как пример: “foot left mount” – эффект будет прикреплен к левой ноге обездвиженной боевой единицы.
Заметьте также, что у некоторых моделей могут отсутствовать те или иные точки прикрепления.
Этим действием Вы привяжете модель к боевой единице со способностью ‘ACnr’, причем цвет команды модели будет соответствовать владельцу боевой единицы. Это также сработает в сочетании со способностями перевоплощения. Если случится, что у модели вдруг исчезнет цвет команды, следующий код исправит ситуацию:
call SetUnitColor(<unit>, GetPlayerColor(GetOwningPlayer(<unit>))) где <unit> - модель прикрепленного эффект
Вообще-то таких способностей должно быть больше, если поискать. Например взять пустышки с невидимыми иконками, которые воспроизводят эффект. Они к примеру доступны после улучшения, а что если взять стандартную и у нее убрать в требованиях технологии.
Для эффектов:
Укрепленные логова 'Arbr' - пустышка с невидимой иконкой, которая есть у логова и сторожевых вышек. Открывается при завершении исследования. Скорее всего больше создана для эффектов. У этих строении пояляются стальное укрепление. Короче железки с четырех сторон.
Шипы 'Aspi' - пустышка с невидимой иконкой, которая есть у всех орочьих строении. Открывается при завершении исследования. Скорее всего больше создана для эффектов. У этих строении появляются шипы.
Надо написать сборник такой по всем абилкам.
27

» WarCraft 3 / Только одно улучщение

Принятый ответ
Таурен Тауреныч, точнее не блокировать, а прятать улучшения (если про улучшения говорим).
пример
Объяснение: Вот нажали, и текущее исследование запущено. Мы ловим начало и завершение этого исследования. Есть три апгрейда, и если выбрано одно из них, то два остальных блочат. Если прерывают через кнопку отмена, то нужно все вернуть как было
Событие - Игрок начинает улучшение
Действие - То блокировать остальные улучшения игрока (через вкладку Игрок делаешь max уровень улучшения ставишь на ноль, тогда игрок не сможет выбрать еще одно)
Событие - Игрок прекращает (прерывает) улучшение (это когда нажимает на отмену) Еще надо проверить, срабатывает ли событие это при уничтожении лаборатории (здания) в тот момент, когда что-то изучает. Если нет, тогда придется добавить в триггер событие "Юнит умирает"
Действие - То вернуть как было.
Событие - Игрок завершает улучшение (короче успешно завершено, никак не откатишь улучшение)
Действие - Тут ..... (ваше действие) подчищаем все и др.
27

» WarCraft 3 / Количество предметов в области

Вот сделал многоразовую бутылку Bottle из доты. Когда подходишь к фонтану, и бутылка становится полной. Еще попробовал сделать так, чтобы обычные сосуды зелии (не целебная вода из фонтана) не были одноразовыми, и можно было у алхимика пополнить жидкость за копейки (будь ходь зелье здоровье, хоть зелье маны).
Поискал в интернете, и что-то иконок не много нашел под вар. Даже норм не было, большинство лишь перекрашенные стандартные иконки. Накачал дофига иконок зелий со всех возможных сайтов.
Конечно, можно в гугл вбить "зелье" и найти хорошую красивую картинку, подогнать под 64х64. Но еще нужно было фотошопом жидкость обрезать нужно было, если нужно как в доте. Этого не стал делать, так как не знаю как это сделать в фотошопе.
Загруженные файлы
27

» WarCraft 3 / Как в хеш-таблице установить null значение?

Принятый ответ
В хеш-таблице изначально возвращает null (это если ничего не записано). Помню делал похожую систему только с итемами, при проверке через Load... проверял не пуста ли ячейка (!=null). По какой-то причине, уже не помню, не всегда так работает, неизвестно от чего система не работает, щас лень браться и искать ошибку.
В вашем понимании null на jass:
 null = Нет боевая единица.
Ответ: чтобы записать null, ничего не надо записывать. Чтобы записать ноль у целого (0) или вещественного (0.00) числа, тоже ничего не надо перезаписывать. Если ничего не записано, вернет null или ноль. Пользуемся дебагами и проверяем.
Еще не попутал ли ты ключи местами? Там на гуи 1, 2 на jass перевернуть надо типа 2, 1. Смотрим
смотрим
есть BJ тоже гуи-команды. конвентируем в код и видим есть SaveUnitHandleBJ и SaveUnitHandle. Нужно представить ключи в таком порядке в каком изложены в нативке SaveUnitHandle а не в SaveUnitHandleBJ (ибо потом вас гуи путает):
parentKey - родительский ключ
childKey - младший ключ
представить хэш-таблицу можно как таблицу Excel, parentKey как строку, а childKey как столбик. И по этим вы находите ячейку. Еще в плюсе хэндлы юзать, по хэндлам будете строки находить. Стираете инфу тоже по хэндлу, по родительскому ключу. А если нужно стереть строку используйте FlushChildHashtable
function SaveUnitHandleBJ takes unit whichUnit, integer key, integer missionKey, hashtable table returns boolean
    return SaveUnitHandle(table, missionKey, key, whichUnit)
endfunction

native SaveUnitHandle takes hashtable table, integer parentKey, integer childKey, unit whichUnit returns boolean
проверка
native HaveSavedHandle takes hashtable table, integer parentKey, integer childKey returns boolean
удаление
native RemoveSavedHandle takes hashtable table, integer parentKey, integer childKey returns nothing
и правильно иницировал хэш-таблицу?
27

» WarCraft 3 / Манипуляции с кругом выделения и не только

IceFog, не глючат. Единственное, что хотел сказать у меня постоянно ОС виндовс 10 высылает мини-окно с ошибкой драйвера. Просто драйвера обновил, и что-то ОС не нрав. Смело игнорирую. Может быть из-за этого? Ноутбук просто новый.
Напрямую только что через игру включал, одно и то же. Локальные включены. Другие карты не глючат, идут нормально.
27

» WarCraft 3 / Иконки на заказ

Нужны иконки для сосудов (бутылки, кувшинов и др)
  1. для прозрачных бутылок нужны разные иконки (степень наполнения: одна иконка бутылки забита полностью full, на другой 3/4, далее половина, 1/4 и пустая бутылка. Что-то начинаю искать, один отстой выдает гугл. Желательно побольше и разных. Это наподобие доты.
  2. кувшин душ. С каждым разом наполняется черным туманом, или подобием. Нужно отобразить что с каждым разом у кувшина появляются трещины. И что может лопнуть.
27

» WarCraft 3 / Количество предметов в области

Принятый ответ
вот так
каждый раз обнуляешь счетчик, перечитываешь все лежащие итемы. Единственное, что когда итем лежит в инвентаре героя, то счетчик не показывает, что увеличилось на +1.
можно конечно вокруг перебирать. Это в фильтр вставляешь, условие что расстояние между героем и итемом не больше определенного радиуса
вспомнилось что-то итем Bottle из доты. там периодически перебирал всех юнитов в области с неполной бутылкой.
Загруженные файлы
27

» WarCraft 3 / Манипуляции с кругом выделения и не только

что-то наработка не хорошая. скачал, открыл карту в редакторе, запустил карту. Загрузилась (интерфейс показался, не было ни войск, одна земля, только значок мыши в центре карты в виде стрелочек, только не зеленого как обычный, а серый), и тут же подвисло все на этом моменте. Лишь музон играл. Никак не мог закрыть. Диспетчер даже не помог. Что-то не так делаю?
27

» WarCraft 3 / Как сделать условие?

Принятый ответ
Alexey103, проверяй дебагом. Выводи числа, проверяй сработал ли блок внутри if then endif, выводи название типа предмета (не выводит, значит ошибка)
здесь ошибка в переменной, вместо Last dropped Item вставить нужно Item being manipulated - поэтому и не работает
объяснение
Item being manipulated (манипулируемый итем) - переменная срабатывает при таких событиях - юнит теряет итем/юнит получает итем/юнит использует итем. Last dropped Item - переменная на последний дропнутый айтем действием "Hero - Drop Item" (если раскрыть это действие, можно увидеть, что при дропе переменная перезаписывается). То есть это триггером дропается, если вручную дропнуть, то ничего не перезапишет. В чем отличие между двумя переменными? Первая показывает итем, который дропают сейчас, а второй показывает итем, который выбросили когда-то триггером через действие "Hero - Drop Item".
в триггерах внизу читаешь хотя бы подсказки? что за переменные и что делают и тд
объяснение работы цикла
ssbbssc, Дурацкие лупы, они в гуи бесполезны, что я тут неправильно сделал? И как ими вообще пользоваться? Переменная count это число предметов в массиве red items. Что оно подбирает?
цикл - повторение одних и тех действий. В гуи есть for each integer A - do actions. Внутрь в эту конструкцию вставляй действия, и они будут повторяться, пока не выполнится условие выхода (например, в скрине ты вписал выполнять от 0 до count). Действия повторяются, меняются разве, что номер integer A.
Внутри блока loop программа выполняет сверху вниз, дойдет до низа. Потом будет выполнять снова эти же действия (сверху-вниз), короче выполняет следующий шаг цикла, потом еще шаг, потом еще шаг и так далее.
loop
	...... //повторяющие действия, называют тело цикла
	exitwhen i > count //условие выхода
	set i = i + 1 //шаг цикла, i - своего рода счетчик цикла
endloop
integer A - в гуи счетчик цикла, который с каждым разом увеличивается на 1 единицу. В гуи так прописано, по-другому можно разве что на jass.
Когда integer A будет больше count (по условию цикла), тогда цикл прервется. Прервать также можно написав exitwhen true
способ
берете функцию quq_CCCP
function CheckItem takes item it, integer count returns boolean
local integer Itemtype = GetItemTypeId(it)
set bj_forLoopAIndex = 0
set bj_forLoopAIndexEnd = count
loop
	exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd 
	
	if udg_reditems[bj_forLoopAIndex] == Itemtype then
		return true
	endif
	
	set bj_forLoopAIndex = bj_forLoopAIndex + 1
endloop
return false
endfunction
где в аргументах it - итем, count - макс. индекс массива
!) берете код вставляете в шапку карты
  1. затем прописываете его в условии. В jngp доступно CS, короче на jass прописать можно
И пример карты
Можно сделать еще легче.
Extremator Что мешает создать базу данных?
в редакторе объектов можно использовать уровни итемов в качестве подразделения на категории (красные итемы - 1 уровень, синие итемы - 2 уровень и так далее). А в триггерах есть команды проверки на уровень итема
Загруженные файлы
27

» WarCraft 3 / Помогите с функцией

через GroupEnumUnitsSelected
не знаю, лучше или хуже. Пусть автор выбирает. Но по-моему лучше вариант ScopteRectuS, Пусть будет
function Trig_Untitled_Trigger_001_Copy_Conditions takes nothing returns boolean
    return( GetUnitTypeId(GetDyingUnit()) == 'halt' )
endfunction

function hideg takes nothing returns nothing
call ShowUnitHide( GetEnumUnit() )
endfunction
function unhideg takes nothing returns nothing
call ShowUnitShow( GetEnumUnit() )
endfunction

function Trig_Untitled_Trigger_001_Copy_Actions takes nothing returns nothing

local unit d = GetDyingUnit()
local player p = GetOwningPlayer(d)
local real x = GetUnitX(d)
local real y = GetUnitY(d)
local group g = CreateGroup()
local integer i = 0

loop
    exitwhen i > 11
    set udg_GROUP[i] = CreateGroup()
    call GroupEnumUnitsSelected(udg_GROUP[i], Player(i), null) //выделяем всех юнитов, которые выделены этим игроком
    set i = i + 1
endloop

call GroupEnumUnitsInRange( g, x, y, 512, null ) //выделяем всех вокруг
call ForGroup( g, function hideg) //прячем

call CreateUnit(p,'eate',x,y,bj_UNIT_FACING) //создаем другой алтарь

call ForGroup( g, function unhideg) //показываем

call DestroyGroup(g) //общую группу удалить можно

//цикл
//теперь игрокам возвращаем подконтрольных юнитов

set i = 0

loop
    exitwhen i > 11
    call SelectGroupForPlayerBJ( udg_GROUP[i],Player(i))
    call DestroyGroup(udg_GROUP[i])
    set i = i + 1
endloop

set g = null
set d = null
 
endfunction

//===========================================================================
function InitTrig_Untitled_Trigger_001_Copy_Copy takes nothing returns nothing
    set gg_trg_Untitled_Trigger_001_Copy_Copy = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Untitled_Trigger_001_Copy_Copy, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition( gg_trg_Untitled_Trigger_001_Copy_Copy, Condition( function Trig_Untitled_Trigger_001_Copy_Conditions ) )
    call TriggerAddAction( gg_trg_Untitled_Trigger_001_Copy_Copy, function Trig_Untitled_Trigger_001_Copy_Actions )
endfunction
все-таки ошибся. простая проверка IsUnitSelected работает на врагов, но в прошлый раз в цикл в цикле не работало почему-то.
Загруженные файлы
27

» WarCraft 3 / Помогите с функцией

ScopteRectuS, неплохо, хорошая система. Пробовал исправить, там условия неправильные и прочее. Но не получается.
IsUnitSelected - проверка не показывает, что вражеский юнит выбран игроком (только через события можно)
Можно еще попробовать через GroupEnumUnitsSelected - выбирает юнитов в группу, который может выделить другой игрок
27

» WarCraft 3 / Помогите с функцией

вот
function Trig_Untitled_Trigger_001_Copy_Conditions takes nothing returns boolean
    return( GetUnitTypeId(GetDyingUnit()) == 'halt' )
endfunction

function abc takes nothing returns boolean
local player p = GetOwningPlayer(GetFilterUnit())
 return IsUnitSelected(GetFilterUnit(),p)
endfunction 

function ASS takes nothing returns nothing
local unit u = GetEnumUnit()
local player p = GetOwningPlayer(u)
local integer i = GetPlayerId(p)

set udg_B[i] = IsUnitSelected(u,p)

set u = null
endfunction

function abd takes nothing returns boolean
local player p = Player(udg_A )
 return IsUnitSelected(GetFilterUnit(),p)
endfunction 

function hideg takes nothing returns nothing
call ShowUnitHide( GetEnumUnit() )
endfunction
function unhideg takes nothing returns nothing
call ShowUnitShow( GetEnumUnit() )
endfunction

function Trig_Untitled_Trigger_001_Copy_Actions takes nothing returns nothing

local unit d = GetDyingUnit()
local player p = GetOwningPlayer(d)
local real x = GetUnitX(d)
local real y = GetUnitY(d)
local group g = CreateGroup()
local integer i = 0

call GroupEnumUnitsInRange(g,x,y,512,Condition(function abc)) //берете выделяете всех юнитов
//самое внимание обратить на функцию ASS, добавил переменную udg_B, важную часть в следующем
//логическая переменная udg_B говорит, что у игрока были выделены юниты около алтаря, или не были
//хотя бы один юнит, и то скажет да"
call ForGroup(g, function ASS)

//цикл
//создаем для каждого игрока группу, которая запомнит всех выделенных юнитов

loop
    exitwhen i > 11 //условие выхода цикла (игроков всего 12)
    if udg_B[i] then //если номер игрока, у которого юниты выделены\, то создаем группу и пикаем всех юнитов
        set udg_GROUP[i] = CreateGroup()
        
        set udg_A = i //запоминаем номер в глобалку\, необходимо перенести значение в фильтр function abd
        call GroupEnumUnitsInRange(udg_GROUP[i],x,y,512,Condition(function abd)) //выделяем всех юнитов, которые выделены этим игроком
    endif
    set i = i + 1
endloop

call GroupClear(g) //очищаем общую группу
call GroupEnumUnitsInRange( g, x, y, 512, null ) //выделяем всех, и выделенных и не выделенных
call ForGroup( g, function hideg) //прячем

call CreateUnit(p,'eate',x,y,bj_UNIT_FACING) //создаем другой алтарь

call ForGroup( g, function unhideg) //показываем

call DestroyGroup(g) //общую группу удалить можно

//цикл
//теперь игрокам возвращаем подконтрольных юнитов

set i = 0

loop
    exitwhen i > 11
    if udg_B[i] then
        call SelectGroupForPlayerBJ( udg_GROUP[i],Player(i))
        call DestroyGroup(udg_GROUP[i])
        
        set udg_B[i] = false
    endif
    set i = i + 1
endloop

set g = null
set d = null
 
endfunction

//===========================================================================
function InitTrig_Untitled_Trigger_001_Copy_Copy takes nothing returns nothing
    set gg_trg_Untitled_Trigger_001_Copy_Copy = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Untitled_Trigger_001_Copy_Copy, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition( gg_trg_Untitled_Trigger_001_Copy_Copy, Condition( function Trig_Untitled_Trigger_001_Copy_Conditions ) )
    call TriggerAddAction( gg_trg_Untitled_Trigger_001_Copy_Copy, function Trig_Untitled_Trigger_001_Copy_Actions )
endfunction
в первой карте ошибку обнаружил, поэтому выслал вторую
Загруженные файлы
27

» WarCraft 3 / Помогите с функцией

hell_bent, честно, не понял что ты хочешь сделать. Ты хочешь выделить (SelectGroupForPlayerBJ дать по контроль игроку) юнитов, которые уже и так выделены этим игроком?
27

» WarCraft 3 / Помогите с функцией

мб ты так хотел? ошибка
local unit d = GetDyingUnit() 
local real x = GetUnitX(d)
local real y = GetUnitY(d)
local group g = CreateGroup()
call GroupEnumUnitsInRange( g, x, y, 512, null)
local unit u
local player p = GetOwningPlayer(d) //будет так правильно, мы проверяем выделен ли владельцем GetDyingUnit
//цикл
loop
exitwhen u == null //условие выхода из цикла (выходит тогда, конца группа будет пуста)
set u = FirstOfGroup(g) //берет первого юнита группы

//если юнит не выбран, тогда удалить из группы. А те кто останутся, никогда не удаляться
if ( not IsUnitSelected(u,p)) then 
	call GroupRemoveUnit(g,u)
endif
endloop
//конец цикла 
проблема выделяется в ( not IsUnitSelected(u,p)) ты можешь не удалить всех юнитов из группы, не будет соблюдено условие выхода u == null (что группа пуста) а значит ОШИБКА. Короче нужно по-другому, например использовать вторую группу, добавляя всех выделенных, а в первой пусть удаляются до конца
посоветовал бы юзать фильтр, отсеивает не нужных. То что предложил ScopteRectuS выше, А то придется юзать более страшные конструкции, например вторую группу заюзать, чтобы добавить в нее.
27

» WarCraft 3 / Требование к покупке предмета

WinneR_302, нужен jngp, там спокойно откроет.
В поле "хп" можно записать к какому классу относится (101 - воин, 102 - маг и др)
Переделал бы для надежности. Кажется не подходит для хранения. Если ударить по итему, то прочности (хп) станет меньше. Либо предмет делаем неуязвимым, либо базу данных с хэшем.