13

» WarCraft 3 / Запрет выбора юнита

Событие: Игрок выбирает юнита
Условие: триггерный юнит = твой юнит
Действие: Отменить выбор или Переключить выбор на своего героя
Загруженные файлы
13

» WarCraft 3 / Как запретить использование предметов?

Тебе нужна абилка Рок, она блокирует герою использовать предметы
Загруженные файлы
13

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

Лучше делать кастомную на основе невидимости волшебницы через дамми каст, там и бафф сразу вешается или постоянную невидимость, стремительность имеет свои баги.
13

» WarCraft 3 / как изменить время внутри таймерного периодического триггера?

Просто создаем real timeEnd типа и сохраняем в ХТ на какой-нибудь хэндл и выгружаем, меняем значение выгружая из ХТ где то и сохраняем новое значение, также с имитацией остановкой можно сохранить через boolean или обзавестись глобалками и менять их значения. Понятно что будет висеть тикающий таймер, но наверное что бы нагрузить игру это довольно много надо таких таймеров-пустышек сделать.
13

» WarCraft 3 / Зрители

Centyrion, Про систему не скажу, а вот что бы было читабельно помещай повторяющиеся действия в циклы.
function F_Init_Players takes nothing returns nothing
    local integer i = 0

    call FogMaskEnable(false)
    call FogEnable(false)

    loop
    exitwhen i >= 9
        set MapControl[i] = ConvertMapControl(0)//MAP_CONTROL_USER
        set i = i + 1
    endloop
    set i = 0
    set MapControl[11] = ConvertMapControl(1)//MAP_CONTROL_COMPUTER

    set Loop[1] = 0
    loop
    exitwhen Loop[1] > GetPlayers()
        set Players[Loop[1]] = Player(Loop[1])
        //from 1 to 12 == from 0 to 11
        if Players[Loop[1]] != Players[11] and Players[Loop[1]] != Players[10] then 
        //исключение для 12 и 11 игрока
        call SetPlayerState(Players[Loop[1]], PLAYER_STATE_RESOURCE_GOLD, 50)
        endif
        set Loop[1] = Loop[1] + 1
    endloop

    if GetPlayerSlotState(Players[10]) == ConvertPlayerSlotState(0) then//PLAYER_SLOT_STATE_EMPTY
        if GetPlayerController(Players[10]) == ConvertMapControl(5) then//MAP_CONTROL_NONE
            set MapControl[10] = ConvertMapControl(1)//MAP_CONTROL_COMPUTER
            call SetPlayerController(Players[10], MapControl[10])
            call SetPlayerName(Players[10],"Союзник")
            call SetPlayerRacePreference(Players[10],RACE_PREF_NIGHTELF)
            call SetPlayerTeam(Players[10],0)
            set Loop[2] = 0

        loop
        exitwhen Loop[2] > GetPlayers() - 2
            //чтоб игроки не нападали друг на друга
            call F_Player_Alliance(Loop[2], true, i, 0, true)
            set Loop[2] = Loop[2] + 1
            set i = i + 1
        endloop
        set i = 0
        endif//MAP_CONTROL_NONE
    endif

    if GetPlayerState(Players[10], ConvertPlayerState(11)) == 1 then//PLAYER_STATE_OBSERVER
        if GetPlayerController(Players[10]) == ConvertMapControl(0) then 
        set MapControl[10] = ConvertMapControl(0)//MAP_CONTROL_USER
        set Observer = Players[10]
        set Players[13] = Player(13)//наш союзник!

        call SetPlayerController(Players[10], MapControl[10])
        call SetPlayerName(Players[10],"Зритель")
        call SetPlayerName(Players[13],"Союзник")
        call SetPlayerState(Players[10],ConvertPlayerState(7),0)//PLAYER_STATE_GIVES_BOUNTY
        call SetPlayerColor(Players[13],ConvertPlayerColor(10))

        call F_Player_Alliance(11, false, 10, 0, true)
        //Враг не сможет атаковать Зрителя но игроков Да
        //а Зритель будет смотреть на него как на врага как и игроки
        call F_Player_Alliance(13, false, 11, 0, false)
        //союзник будет смотреть на 12 игрока как на Врага
        //13 игрок Союзник и он не умеет нападать на Зрителя или на Игроков
        call F_Player_Alliance(10, false, 13, 0, true)
        //для Зрителя 13 игрок Союзник

        set Loop[3] = 0
        loop
        exitwhen Loop[3] > GetPlayers()-2
            call F_Player_Alliance(Loop[3], true, i, 0, true)//и на себе подобных
            set Loop[3] = Loop[3] + 1
            set i = i + 1
        endloop
        set i = 0

        endif//MAP_CONTROL_USER
    endif//PLAYER_STATE_OBSERVER


    if IsMapFlagSet(MAP_RANDOM_RACES) then
        loop 
        exitwhen i >= 9
            call SetPlayerRacePreference(Players[i],ConvertRacePref(1))
            set i = i + 1
        endloop
        call SetPlayerRacePreference(Players[11],ConvertRacePref(8))
    endif

    if IsMapFlagSet(MAP_RANDOM_HERO) then
        call SetMapFlag(MAP_RANDOM_HERO, false)
    endif

endfunction
13

» WarCraft 3 / Невосприимчивость к аурам

Как вариант можно добавлять для этих юнитов отдельную классификацию при касте и настроить все ауры что бы они не действовали на эту классификацию.
Вот допустим код твоего скила.
function Trig_Spell_Actions takes nothing returns nothing
    call UnitAddAbility( GetSpellTargetUnit(), 'ACm2')
    call UnitAddType(GetSpellTargetUnit(), UNIT_TYPE_MECHANICAL)
endfunction

function Trig_Spell_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A001'
endfunction

//===========================================================================
function InitTrig_Spell takes nothing returns nothing
    local trigger t = CreateTrigger()
    local integer index

    set index = 0
    loop
        call TriggerRegisterPlayerUnitEvent(t, Player(index), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition( t, Condition( function Trig_Spell_Conditions ) )
    call TriggerAddAction( t, function Trig_Spell_Actions )
    
    set t = null
endfunction
Юниту выдается иммунка архимонда и добавляем ему классификацию механического, а в настройках аур указываем действует на органических.
Загруженные файлы
13

» WarCraft 3 / как на гуи/jass сделать проверку по таймеру

В периодическом таймере проверять условия пока они не будут равны и таймер остановится или просто по окончанию таймера проверять условия?(В этом случае таймер остановится независимо равны будут условия или нет)
1 вариант
globals
    boolean A_CONDITION = true
    boolean B_CONDITION = false
endglobals


function Timer_Time takes nothing returns nothing
    if A_CONDITION and B_CONDITION then //Будет прокручивать таймер пока условия не будут равны
        call PauseTimer(GetExpiredTimer())
        //Твои действия
        call DestroyTimer(GetExpiredTimer())
    endif
endfunction

function Timer_Actions takes nothing returns nothing
    call TimerStart( CreateTimer(), 0.01, true, function Timer_Time)
endfunction

//===========================================================================
function InitTrig_Timer takes nothing returns nothing
    set gg_trg_Timer = CreateTrigger(  )
    call TriggerRegisterTimerEventSingle( gg_trg_Timer, 0.00 )
    call TriggerAddAction( gg_trg_Timer, function Timer_Actions )
endfunction
2 вариант
function Timer_Time takes nothing returns nothing
    local boolean a = true
    local boolean b = true
    
    if a and b then //Условия
        //Твои действия
    endif
    
    call PauseTimer(GetExpiredTimer())
    call DestroyTimer(GetExpiredTimer())
endfunction

function Timer_Actions takes nothing returns nothing
    local real time = 5.00
    
    call TimerStart( CreateTimer(), time, false, function Timer_Time)
endfunction

//===========================================================================
function InitTrig_Timer takes nothing returns nothing
    set gg_trg_Timer = CreateTrigger(  )
    call TriggerRegisterTimerEventSingle( gg_trg_Timer, 0.00 )
    call TriggerAddAction( gg_trg_Timer, function Timer_Actions )
endfunction
13

» WarCraft 3 / отслеживание захода в воду

Можно чекать через точку или еще лучше через координаты. Как можно проверить глубину? что такое глубина? это 1. Что там нельзя ходить пешим 2.Там плавают лодки. И что такое мелководье? Там где могут ходить и пешие и плавать лодки. Из этого мы уже можем путем двух проверок сделать.
function IsWaterCheck takes real x, real y, boolean shallow, boolean deep returns boolean
    local boolean Log
    
    if shallow and not deep then
        set Log = not IsTerrainPathable( x, y, PATHING_TYPE_FLOATABILITY) and not IsTerrainPathable( x, y, PATHING_TYPE_WALKABILITY)
    elseif deep and not shallow then
        set Log = not IsTerrainPathable( x, y, PATHING_TYPE_FLOATABILITY) and IsTerrainPathable( x, y, PATHING_TYPE_WALKABILITY)
    elseif deep and shallow then
        set Log =  not IsTerrainPathable( x, y, PATHING_TYPE_FLOATABILITY)
    endif
        
    return Log
endfunction
Если в игре присутствует вода в виде декора. Тут уже добавляем чек на декор к этой функции.
13

» WarCraft 3 / ИИ и главное здание

Если из-за автокаста способности сбиваются другие приказы
1 Попробуй отключить автокаст
2 Сделай способность без автокаста, возьми волну лечения у ловца духов(темный охотник).
3 Сделай триггерное лечение.
4 Написать ИИ поведение приказов
13

» WarCraft 3 / Оптимизация Выполнения Последовательности Кода

Я вот так просто делаю.
function UnitHaveItem takes unit UnitItem, integer ItemTypeID returns boolean
    local integer i = 0
    local boolean ItemLog = false
    
    loop
    exitwhen i >= bj_MAX_INVENTORY
        if GetItemTypeId(UnitItemInSlot(UnitItem, i)) == ItemTypeID then
            set ItemLog = true
        endif
    set i = i + 1
    endloop
    
    return ItemLog
endfunction

function A takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    
    if UnitHaveItem( caster, 'I000') and UnitHaveItem( caster, 'I001') and UnitHaveItem( caster, 'I002') and UnitHaveItem( caster, 'I003') then
        //Твои действия
    endif
    
    set caster = null
endfunction
можно конечно извращаться и делать так например
function UnitHaveItem takes unit UnitItem, integer ItemTypeID returns boolean
    local integer i = 0
    local boolean ItemLog = false
    
    loop
    exitwhen i >= bj_MAX_INVENTORY
        if GetItemTypeId(UnitItemInSlot(UnitItem, i)) == ItemTypeID then
            set ItemLog = true
        endif
    set i = i + 1
    endloop
    
    return ItemLog
endfunction

function CheckItems takes unit caster, integer ItemA, integer ItemB, integer ItemC, integer ItemD, integer ItemE returns boolean
    return UnitHaveItem( caster, ItemA) and UnitHaveItem( caster, ItemB) and UnitHaveItem( caster, ItemC) and UnitHaveItem( caster, ItemD) and UnitHaveItem( caster, ItemE)
endfunction

function B takes nothing returns nothing
    local unit Unit = GetTriggerUnit()
    if CheckItems(Unit, 'I000', 'I001', 'I002', 'I003', 'I004') then
        //True
    else
        //False
    endif
    set Unit = null
endfunction
13

» WarCraft 3 / Способности и алгоритмы на заказ

rsfghd, был бы еще мемхак,южапи или реф и можно было бы героя за молнией крутить для реалистичности :)
13

» WarCraft 3 / Способности и алгоритмы на заказ

rsfghd, Даже не знаю, не видел такие настройки, я думал нужен триггерный вампиризм🐸
13

» WarCraft 3 / Способности и алгоритмы на заказ

Выполнение заказа

Заклинание готово!

Заказчик: Meddin
Способность: Живительная волна
Выполнено: Да

Описание
Скопируй способность, даммика и триггер LifeWave, в триггере укажи равкод способности и даммика

Загруженные файлы
13

» WarCraft 3 / Способности и алгоритмы на заказ

Выполнение заказа
Заказчик: Гогонаш
Способность: Аура вампиризма для дальников
Выполнено: Да

Описание
Сделал через готовую систему отлова урона. Скопируй все нестандартные абилки и баф, в триггере системе отлова урона укажи равкоды 2х абилок, в триггере вампиризма укажи равкод бафа от ауры.
Загруженные файлы
13

» WarCraft 3 / Радиус атаки

Super cool, Добавил с правками на случайного юнита, спасибо rsfghd
В коде есть комментарии для обучения Jass-у, как все устроено.
Загруженные файлы
13

» WarCraft 3 / Радиус атаки

Super cool, Jass это встроенный язык программирования варкрафта, т.е код что на GUI - пользовательский интерфейс, только в виде кода. GUI ограничен, на нем могут вылезти утечки. Из-за чего могут быть лаги в картах.
подробнее про Jass Тут
Ну и конечно нужен JNGP, если на 1.26 патче или рефорджет. Скачать можно тут
Создаем триггер и конвертируем его в текст. Затем копируем и вставляем код.
Конвертируем в текст
udg_Tower - твоя башня, триггер рассчитан на 1 башню если нужно на несколько, используй другой код и заноси каждую башню в группу
Тогда нужно создать группу для башен, т.е GroupTowers.
Создаем GUI переменную
Код для 1 башни
scope LightningAutoCast

globals
   private unit filterUnit //Юнит для перебора
   private group GroupEnumG = CreateGroup() //Группа для перебора юнитов
   //udg_Tower = Башня
endglobals

native UnitAlive takes unit id returns boolean //Нативка на жив ли юнит

function DistanceBetweenXY takes real x1, real y1, real x2, real y2 returns real //Дистанция между координатами
   return SquareRoot((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)) 
endfunction

function AOE_Lightning_Filter takes nothing returns boolean //Фильтр функция
        local real x = GetUnitX(udg_Tower) //Координата Х башни
        local real y = GetUnitY(udg_Tower) //Координата Y башни
        local real x1
        local real y1
        
        set filterUnit = GetFilterUnit()
        
        set x1 = GetUnitX(filterUnit) //Координата X фильтр юнита
        set y1 = GetUnitY(filterUnit) //Координата Y фильтр юнита
        
        return IsUnitEnemy(filterUnit, GetOwningPlayer(udg_Tower)) and filterUnit != udg_Tower and not IsUnitType(filterUnit, UNIT_TYPE_STRUCTURE) and DistanceBetweenXY( x, y, x1, y1) > 500
        //Условия: Юнит враг Игроку Башни и Юнит не равен самой Башни и Юнит не является зданием и Дистанция между координатами юнита и башни > 500
endfunction

function AOE_Lightning_Actions takes nothing returns nothing
        local real radius = 1000 // Радиус
        local real x = GetUnitX(udg_Tower) //Координата Х башни
        local real y = GetUnitY(udg_Tower) //Координата Y башни
        local unit uf // Юнит для перебора в цикле
        
        call GroupEnumUnitsInRange(GroupEnumG, x, y, radius, function AOE_Lightning_Filter) // Пикаем юнитов в радиусе от координат башни и перебираем в функции фильтре
        loop
            set uf = FirstOfGroup(GroupEnumG) // GroupPickRandomUnit(GroupEnumG) -- Если нужен случайный юнит в радиусе, удаляем FirstOfGroup(GroupEnumG) и ставим эту функцию
            exitwhen uf == null
            if UnitAlive(uf) then 
                call IssueTargetOrder(udg_Tower, "chainlightning", uf) //Кастуем молнию на юнита
            endif
            call GroupRemoveUnit( GroupEnumG, uf) //Удаляем юнита из группы
            set uf = null //Обнуляем переменную
        endloop
        call GroupClear(GroupEnumG) //Очищаем группу
        
endfunction

function InitTrig_LightningAutoCast takes nothing returns nothing
call TimerStart( CreateTimer(), 0.03, true, function AOE_Lightning_Actions) //Создаем периодический таймер
endfunction

endscope
Код для несколько башень
scope LightningAutoCastGroup

globals
   private unit filterUnit //Юнит для перебора
   private group GroupEnumG = CreateGroup() //Группа для перебора юнитов
   //udg_Tower = Башня
endglobals

native UnitAlive takes unit id returns boolean //Нативка на жив ли юнит

function DistanceBetweenXY takes real x1, real y1, real x2, real y2 returns real //Дистанция между координатами
   return SquareRoot((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)) 
endfunction

function AOE_Lightning_Filter takes nothing returns boolean //Фильтр функция
        local real x = GetUnitX(GetEnumUnit()) //Координата Х башни
        local real y = GetUnitY(GetEnumUnit()) //Координата Y башни
        local real x1
        local real y1
        
        set filterUnit = GetFilterUnit()
        
        set x1 = GetUnitX(filterUnit) //Координата X фильтр юнита
        set y1 = GetUnitY(filterUnit) //Координата Y фильтр юнита
        
        return IsUnitEnemy(filterUnit, GetOwningPlayer(GetEnumUnit())) and filterUnit != GetEnumUnit() and not IsUnitType(filterUnit, UNIT_TYPE_STRUCTURE) and DistanceBetweenXY( x, y, x1, y1) > 500
        //Условия: Юнит враг Игроку Башни и Юнит не равен самой Башни и Юнит не является зданием и Дистанция между координатами юнита и башни > 500
endfunction

function AOE_Lightning_Actions takes nothing returns nothing
        local real radius = 1000 // Радиус
        local real x = GetUnitX(GetEnumUnit()) //Координата Х башни
        local real y = GetUnitY(GetEnumUnit()) //Координата Y башни
        local unit uf // Юнит для перебора в цикле
        
        call GroupEnumUnitsInRange(GroupEnumG, x, y, radius, function AOE_Lightning_Filter) // Пикаем юнитов в радиусе от координат башни и перебираем в функции фильтре
        loop
            set uf = GroupPickRandomUnit(GroupEnumG) // GroupPickRandomUnit(GroupEnumG) -- Если нужен случайный юнит в радиусе, удаляем FirstOfGroup(GroupEnumG) и ставим эту функцию
            exitwhen uf == null
            if UnitAlive(uf) then 
                call IssueTargetOrder(GetEnumUnit(), "chainlightning", uf) //Кастуем молнию на юнита
            endif
            call GroupRemoveUnit( GroupEnumG, uf) //Удаляем юнита из группы
            set uf = null //Обнуляем переменную
        endloop
        call GroupClear(GroupEnumG) //Очищаем группу
        
endfunction

function AOE_Lightning_Actions_GroupTower takes nothing returns nothing
    call ForGroup( udg_GroupTowers, function AOE_Lightning_Actions)
endfunction


function InitTrig_LightningAutoCastGroup takes nothing returns nothing
call TimerStart( CreateTimer(), 0.03, true, function AOE_Lightning_Actions_GroupTower) //Создаем периодический таймер
endfunction

endscope
Результат для 1 башни
Результат для группы башен
13

» WarCraft 3 / Радиус атаки

Super cool, тогда перебирай юнитов в радиусе 1000 и сравнивай дистанцию, поставь условие если расстояние между точками выбранного юнита и самой башни > 500, использовать цепную молнию.
но это лучше делать на Jass-е.
13

» WarCraft 3 / Радиус атаки

Увеличить дальность атаки башни до 1000(В Редакторе Объектов рядом с уроном Атаки) либо уменьшить радиус способности до 500 в триггерах
13

» WarCraft 3 / Как удалить анимацию у модели?

Открываем модель через Mdlvis
  1. Заходим во вкладку Модули -> Редактор Анимации -> Анимки
  2. Выбираем нужную анимацию и удаляем
  3. Сохраняем модель
Инструкция по стрелочкам
Загруженные файлы
13

» WarCraft 3 / Как дать приказ юниту на которого применили способность?

Вычислить 2 юнита при касте
GetTriggerUnit() это юнит каста
GetSpellTargetUnit() или в ГУИ как на скрине это юнит на которого кастует юнит
2 юнита нашли.
а дальше делаем с ними что угодно
Загруженные файлы
13

» WarCraft 3 / Редактор модлелей.

Через что делаете модель? В Mdlvis-e в редакторе анимации нужно смотреть как привязаны меши к кости, возможно неправильно связаны меши(точки на модели).