Канал? Никаким. Если хочешь через гуи кастовать скилы, то нужно пилить на основе другого скила, а не канала.
Это ложь.
Cancel, кинь сюда скриншоты способностей, чтобы было видно, какой ID приказа у этих способностей. Или хотя бы сами ID можешь дать. После этого я скажу, как вызвать на ГУИ.
ID у способностей на основе "Канал" выставляется тут (выделено жёлтым).
Скриншот
Как скастовать способность на основе канала через GUI?
У способностей на основе канала есть поле Basic Order ID. Каждой способности на основе канала его можно поменять.
Пусть наша способность называется G.
Способ 1.
Нужно узнать, какая базовая способность вызывается тем же ID, что выбран у G. Узнать, какой приказ вызывает способность, можно, глянув у способности после Text - Order String (рус. Текст - Порядок строк).
В триггере нужно выбрать Actions -> Unit -> Issue Order [нужный тип приказа]. После этого в выпадающем списке необходимо выбрать найденную базовую способность.
Это можно сделать в стандартном WE.
Скриншот
Остальные два способа требуют JNPG.
Способ 2.
В триггере нужно выбрать Actions -> Unit -> Issue Order [нужный тип приказа] (Takes String). После этого в поле Value (рус. Значение) переписать указанный у способности G ID приказа.
Скриншот
Способ 3.
В триггере нужно выбрать Actions -> Unit -> Issue Order [нужный тип приказа] (Takes Ordercode). После этого в поле Function выбрать JASS Code и в новом окне в поле Value (рус. Значение) написать численный ID приказа способности G. Каждый численный ID уникально ассоциирован со строковым ID. Как они соотносятся, можно найти в этой библиотеке.
Оптимизаторы любят перетаскивать все строки прямо в код, спецом WTS никто не юзает, есть даже функция GetLocalizedString - берет строку из WTS нужного языка, но кто это юзал?
Вот я собираюсь так сделать, когда карта будет готова, но не знаю как.
Сама игра берет название карты, отображаемое именно списке карт (не на загрузочном экране, а в меню), из заголовка .w3x-файла (наверное, игре так делать проще, чем подгружать в память всю карту и wts-ник).
Хм.
Но когда я менял название карты только в .wts, оно также поменялось и в меню выбора карты.
Бтв, чтобы перевести название карты в меню игры, то придется менять заголовок самого файла в HEX редаторе. У меня так, к слову, были траблы с кодировкой кириллицы. Пришлось сделать рандомную карту с нужным названием, а потом скопировать этот кусок единиц и нуликов в переводимую карту.
Вот тут не понял. Как правило, название карты хранится в самой первой строке в .wts. Что же произошло в твоём случае?
Да чего их помнить, баффы стандартные в РО открыть и глянуть.
Для конкретной карты некоторые из них вовсе могут не присутствовать.
А хотите навороченные спеллы - пишите на JASS, там можно сделать 1 функцию, которая проверяет наличие дизейблов на юните, и вызывать её везде, где нужно.
Очень грустно, но триггерный приказ применения Веерного броска всё-таки сбивает текущий приказ у юнита. Лишь при ручном применении всё нормально.
Это же глупость. При ручном применении делается такой же триггерный приказ, но уже внутри движка. Потому либо способность сбивает текущую очередь приказов, либо нет. Веерный Бросок наверняка сбивает.
не был ли герой оглушён, не наложено ли на него молчание, не умер ли он, не происходит ли на него телепортация, ну и вроде ещё что-то.
Достаточно все дизейблы прописать, ничего сложного.
UPD: у некоторых способностей действительно ручное применение не сбивает текущую очередь приказов, но при триггерном приказе, очередь сбивается. Самый простой пример такой способности - Укрыться за щитом.
Если сдвигаешь в ГУИ, то да. А вот если через SetUnitX и SetUnitY (это JASS), ничего не сбивается.
Далее. Лучше герою дать способность на основе канала, а при её использовании создавать даммика, который и будет делать веерный бросок. Также можно будет настроить, может ли герой кастовать что-нибудь ещё, пока твой веерный бросок используется.
Также стоит убрать "Ждать" и заменить это таймером.
Ошибки зависят от pjass.exe.
У меня пишет ошибку несоответствия типов (cannot convert code to boolexpr) только там, где я передаю code как аргумент, а не прямую ссылку на функцию.
private function AddMinionAbilityTrigger takes integer T, code init, code leave returns nothing
if init != null then
set MinionAbilityHomeInit[T] = CreateTrigger()
call TriggerAddCondition(MinionAbilityHomeInit[T], Condition(init))
endif
if leave != null then
set MinionAbilityFieldInit[T] = CreateTrigger()
call TriggerAddCondition(MinionAbilityFieldInit[T], Condition(leave))
endif
endfunction
как это возможно
Эмпирическим путём выяснил, что JASS забивает на возвращаемый тип. Я делал тесты, где действия и условия у триггеров возвращают real, при этом всё работало. Самый наглядный пример этого есть в структурах.
Код ниже.
struct A
method M takes nothing returns nothing
call K.execute()
endmethod
stub method K takes nothing returns nothing
call DisplayTextToPlayer(Player(0), 0., 0., "Message")
endmethod
endstruct
Преобразуется вот во что.
globals
//JASSHelper struct globals:
constant integer si__A=1
integer si__A_F=0
integer si__A_I=0
integer array si__A_V
trigger st__A_K
trigger array st___prototype2
integer f__arg_integer1
integer f__arg_this
endglobals
//Generated method caller for A.K
function sc__A_K takes integer this returns nothing
call DisplayTextToPlayer(Player(0), 0., 0., "Message")
endfunction
//Generated method executor for A.K
function sx__A_K takes integer this returns nothing
set f__arg_this=this
call TriggerExecute(st__A_K)
endfunction
//Generated allocator of A
function s__A__allocate takes nothing returns integer
local integer this=si__A_F
if (this!=0) then
set si__A_F=si__A_V[this]
else
set si__A_I=si__A_I+1
set this=si__A_I
endif
if (this>8190) then
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Unable to allocate id for an object of type: A")
return 0
endif
set si__A_V[this]=-1
return this
endfunction
//Generated destructor of A
function s__A_deallocate takes integer this returns nothing
if this==null then
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Attempt to destroy a null struct of type: A")
return
elseif (si__A_V[this]!=-1) then
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Double free of type: A")
return
endif
set si__A_V[this]=si__A_F
set si__A_F=this
endfunction
function sc___prototype2_execute takes integer i,integer a1 returns nothing
set f__arg_integer1=a1
call TriggerExecute(st___prototype2[i])
endfunction
function sc___prototype2_evaluate takes integer i,integer a1 returns nothing
set f__arg_integer1=a1
call TriggerEvaluate(st___prototype2[i])
endfunction
//Struct method generated initializers/callers:
function sa__A_K takes nothing returns boolean
local integer this=f__arg_this
call DisplayTextToPlayer(Player(0), 0., 0., "Message")
return true
endfunction
function sa___prototype2_s__A_K takes nothing returns boolean
local integer this=f__arg_integer1
call DisplayTextToPlayer(Player(0), 0., 0., "Message")
return true
endfunction
function jasshelper__initstructs7678703 takes nothing returns nothing
set st__A_K=CreateTrigger()
call TriggerAddCondition(st__A_K,Condition( function sa__A_K))
call TriggerAddAction(st__A_K, function sa__A_K)
set st___prototype2[1]=CreateTrigger()
call TriggerAddAction(st___prototype2[1],function sa___prototype2_s__A_K)
call TriggerAddCondition(st___prototype2[1],Condition(function sa___prototype2_s__A_K))
endfunction
Тут как действие триггера передаются функция, что возвращает boolean.
Наверняка есть материалы или узлы, где не проставлены текстуры или тип (Blend, Additive и пр.)
Прикрепите модель к посту, никто не будет качать ваш архив.
local boolexpr b = Condition(function A)
call GroupEnumUnitsInRange(g, x, y, 900, b)
Не надо такие сложности, можно сразу function A передавать. Да и в boolexpr можно что угодно делать, а не только возвращать логическую.
Вот один из примеров, как я их использую. Отсеиваю ненужных в фильтре и там же выполняю необходимые действия. Так как возвращаемый тип nothing, то фильтр всегда возвращает 0, что является ложью, и потому никто в группу не добавляется.
static method filter takes nothing returns nothing
local Minion m = GetUnitUserData(GetFilterUnit())
if IsUnitMinion(GetFilterUnit()) and IsUnitType(m.minion, UNIT_TYPE_GROUND) and m.isFieldAlive and m.owner == TransCaster.owner and m.data.nonheroic then
if m.typ != KnightId then
call BuffInspiration.launch(m, TransCaster, DefaultArmorBonus, DefaultMoveSpeedBonus)
elseif not TransKnightPresense then
set TransKnightPresense = m != TransCaster
endif
endif
endmethod
private static Minion TransCaster
private static boolean TransKnightPresense
method cooldownEnd takes nothing returns nothing
local Minion m = caster
local integer bonus
set TransCaster = m
set TransKnightPresense = false
call GroupEnumUnitsInRange(bj_lastCreatedGroup, GetUnitX(m.minion), GetUnitY(m.minion), abildata.range, function thistype.filter)
if m.data.upgrade[Knight.LordsId] then
set bonus = B2I(TransKnightPresense) * Knight.Lords_ArmorByKnight
set m.s_physarm = bonus
set m.s_magcarm = bonus
call m.updateArmor()
endif
endmethod
Разницы между Filter() и Condition() нет. Обе функции создают boolexpr, который можно использовать как условия в функциях групп, кланов и событий триггеров и для создания условий в триггерах. Текущий проверяемый объект можно получить с помощью функции GetFilter<>(), где <> - имя объекта (Unit, Item, Player). А ещё их можно вот так использовать.
К сожалению.
Он даже работает если запаузить через некоторое время, а ещё через некоторое время вновь его запустить. Как только таймер истечёт, TimerGetRemaining будет возвращать значение оставшегося времени перед последней паузой.
// Test PauseTimer outside timer callback for nonperiodic timer
function GetT1Conf takes nothing returns nothing
call ClearTextMessages()
call DebugMsg("\nRemaining: " + R2SX(TimerGetRemaining(T1)))
call DebugMsg("Elapsed: " + R2SX(TimerGetElapsed(T1)))
call DebugMsg("Timeout: " + R2SX(TimerGetTimeout(T1)))
endfunction
function callback1 takes nothing returns nothing
set Counter1 = Counter1 + 1
call DebugMsg("\nRemaining in callback: " + R2SX(TimerGetRemaining(T1))) // outputs time remaining that was during last pause.
call DebugMsg("Elapsed in callback: " + R2SX(TimerGetElapsed(T1))) // outputs TimerGetTimeout - (time remaining that was during last pause).
call DebugMsg("Timeout in callback: " + R2SX(TimerGetTimeout(T1))) // correct.
call DebugMsg(I2S(Counter1))
endfunction
function f5 takes nothing returns nothing
call TimerStart(T1, 1., Periodic, function callback1)
call DebugMsg("\nResumed")
call GetT1Conf()
endfunction
function f4 takes nothing returns nothing
call PauseTimer(T1)
call DebugMsg("\nPaused")
call GetT1Conf()
call TimerStart(T3, 1., false, function f5)
endfunction
function f3 takes nothing returns nothing
call TimerStart(T1, 8., Periodic, function callback1)
call TimerStart(T3, 2., false, function f4)
endfunction
function f2 takes nothing returns nothing
call TimerStart(T1, 1., Periodic, function callback1)
call DebugMsg("\nResumed")
call GetT1Conf()
call TimerStart(T3, 2., false, function f3)
endfunction
function f1 takes nothing returns nothing
call PauseTimer(T1)
call DebugMsg("\nPaused")
call GetT1Conf()
call TimerStart(T3, 1., false, function f2)
endfunction
function TimerTest_Actions takes nothing returns nothing
call TimerStart(T1, 8., Periodic, function callback1)
call TimerStart(T3, 1., false, function f1)
endfunction
function TimerTest takes nothing returns nothing
set trig = CreateTrigger( )
call TriggerRegisterTimerEvent(trig, 1., false)
call TriggerAddAction( trig, function TimerTest_Actions )
endfunction
globals
trigger trig
constant timer T1 = CreateTimer()
constant timer T3 = CreateTimer()
integer Counter1 = 0
boolean Periodic = false // no bugs for 'true' value.
endglobals
» WarCraft 3 / Руны
В настройках руны стоит галка напротив "Мгновенное применение"?
» WarCraft 3 / Странный Wurst
Ред. PT153
» WarCraft 3 / Триггерное действие "применить способность"
Cancel, кинь сюда скриншоты способностей, чтобы было видно, какой ID приказа у этих способностей. Или хотя бы сами ID можешь дать. После этого я скажу, как вызвать на ГУИ.
ID у способностей на основе "Канал" выставляется тут (выделено жёлтым).
У способностей на основе канала есть поле Basic Order ID. Каждой способности на основе канала его можно поменять.
Пусть наша способность называется G.
Способ 1.
Нужно узнать, какая базовая способность вызывается тем же ID, что выбран у G. Узнать, какой приказ вызывает способность, можно, глянув у способности после Text - Order String (рус. Текст - Порядок строк).
В триггере нужно выбрать Actions -> Unit -> Issue Order [нужный тип приказа]. После этого в выпадающем списке необходимо выбрать найденную базовую способность.
Это можно сделать в стандартном WE.
Способ 2.
В триггере нужно выбрать Actions -> Unit -> Issue Order [нужный тип приказа] (Takes String). После этого в поле Value (рус. Значение) переписать указанный у способности G ID приказа.
В триггере нужно выбрать Actions -> Unit -> Issue Order [нужный тип приказа] (Takes Ordercode). После этого в поле Function выбрать JASS Code и в новом окне в поле Value (рус. Значение) написать численный ID приказа способности G. Каждый численный ID уникально ассоциирован со строковым ID. Как они соотносятся, можно найти в этой библиотеке.
» WarCraft 3 / Странный Wurst
» WarCraft 3 / Странный Wurst
» WarCraft 3 / Перевод карты без предоставления исходников
» WarCraft 3 / Перевод карты без предоставления исходников
» WarCraft 3 / Перевод карты без предоставления исходников
» WarCraft 3 / Перевод карты без предоставления исходников
Но когда я менял название карты только в .wts, оно также поменялось и в меню выбора карты.
» WarCraft 3 / Перевод карты без предоставления исходников
» WarCraft 3 / Воскрешение в мультиплеере
Sergarr:
» WarCraft 3 / авторский перевод WarCraft 3
Ред. PT153
» WarCraft 3 / Актирование способности через триггер?
BHbn - Banish (отключает атаку)
Bclf - Cloud (отключает атаку зданиям)
Bbmg - Control Magic (для суммонов)
Bply - Polymoph
Bdvv - Devour
BOhx - Hex
Bfrz - Freezing Breath (отключает здания)
BUim - Impale
Bpos - Possession
BUsl - Sleep
Bcyc, Bcy2 - Cyclone
BEer - Entangling Roots (вроде отключает атаку)
BNcs - Cluster Rockets
BNdo - Doom
BNsi - Silence
BNso - Soul Burn
BSTN, BPSE - Stunned (первый обычно не используется)
BNvc - Volcano
» WarCraft 3 / Как узнать кол-во единиц атаки у юнита?
» WarCraft 3 / Актирование способности через триггер?
Для конкретной карты некоторые из них вовсе могут не присутствовать.
А хотите навороченные спеллы - пишите на JASS, там можно сделать 1 функцию, которая проверяет наличие дизейблов на юните, и вызывать её везде, где нужно.
Ред. PT153
» WarCraft 3 / Актирование способности через триггер?
Это же глупость. При ручном применении делается такой же триггерный приказ, но уже внутри движка. Потому либо способность сбивает текущую очередь приказов, либо нет. Веерный Бросок наверняка сбивает.Ред. PT153
» WarCraft 3 / Актирование способности через триггер?
Далее. Лучше герою дать способность на основе канала, а при её использовании создавать даммика, который и будет делать веерный бросок. Также можно будет настроить, может ли герой кастовать что-нибудь ещё, пока твой веерный бросок используется.
Также стоит убрать "Ждать" и заменить это таймером.
Ред. PT153
» WarCraft 3 / Мифический Filter
У меня пишет ошибку несоответствия типов (cannot convert code to boolexpr) только там, где я передаю code как аргумент, а не прямую ссылку на функцию.
Код ниже.
» WarCraft 3 / Актирование способности через триггер?
» WarCraft 3 / Снова проблема с модель!
» WarCraft 3 / Снова проблема с модель!
Прикрепите модель к посту, никто не будет качать ваш архив.
Ред. PT153
» WarCraft 3 / Мифический Filter
Вот один из примеров, как я их использую. Отсеиваю ненужных в фильтре и там же выполняю необходимые действия. Так как возвращаемый тип nothing, то фильтр всегда возвращает 0, что является ложью, и потому никто в группу не добавляется.
Ред. PT153
» WarCraft 3 / Мифический Filter
Ред. PT153
» WarCraft 3 / Timer Exploit на 1.26
Он даже работает если запаузить через некоторое время, а ещё через некоторое время вновь его запустить. Как только таймер истечёт, TimerGetRemaining будет возвращать значение оставшегося времени перед последней паузой.
Ред. PT153
» WarCraft 3 / Помогите, пожалуйста, сделать способность
PS: тут GUI, указывайте в описании вопроса, как надо делать.