Ev3nt, только эффект способности также может влиять и на портреты. там белые портретики. знаю, что приведен как пример этот случай. Но в основном больше и нигде использовать этот эффект нельзя (кроме мем хака), почему нельзя изменить скины? почему я должен тысячу копии моделей импортировать для таких случаев.
DarkLigthing, возможно ты и прав. но я существенно плохого то и не вижу, озвучили "хорошо". мб я глухой (в реале так и есть). но отмечу, что произносят одни те же фразы. ну тут же в рефордже то же играют, смягчают голос и пр.
yellyex:
отличное видео
старая озвучка намного колоритнее, в новой все актёры слишком спокойные
из новой озвучки лучше только таурен (и то в большой степени из-за неудачного эффекта окружения, но по напряжению голоса всё равно проигрывает, спокойный слишком. как будто не на войне, а у камина чай с плюшками пьёт).
но в целом сойдёт, комьюнити всегда придирается
в любом случае теперь у нас будет две озвучки, а мы всегда сможем выбрать ту, что по душе
они мало чем отличаются, на чуть чуть. где то хуже где то лучше. мне немного понрав рефорджа, просто старая либо слишком эмоциональна, или просто поднадоела: повторяют одни и те же фразы, их стоит увеличить
ну и бывает и хуже, у рефордж тоже не идеал. где то старые получше: по звучанию, тембру голоса, и пр
Есть и такие изменения: вот Рохан, к рефорджа спокойный какой то старческий голос, а в старой озвучке: молодой крикливый голос, кричащий вечно спешит куда то
Начало этой способности ловится событиями "юнит применяет способность", "юнит завершает способность", "юнит прекращает способность". А отмена ловится приказом. Приказом хорошо ловится (начало, отмена).
DopaMine, ну пишешь, по идее триггер сработал у GetTriggerPlayer()
GetTriggerPlayer - игрок триггера
if GetLocalPlayer() == GetTriggerPlayer() then
call ClearTextMessages()
endif
прочитай про статью GetLocalPlayer() на нашем сайте
константа GetLocalPlayer() возвращает локального игрока, у которого запущена игра. Допустим есть 2 игрока, играющие между собой. на машине первого игрока GetLocalPlayer() вернет первого, на машине второго игрока GetLocalPlayer() вернет второго игрока. Вообще между ними должна сихронизация. иначе при неправильном коде при сработке вылетает и все.
Главное просто условие записать. "локал игрок == твой игрок"
И ещё: как на основе канала сделать способность, которая не прервёт текущего приказа? Не нашёл чё-то. P.S. Рёв не подходит, ибо мне нужно одновременно иметь 11 таких абилок(с разным ID приказа)
очень сложно понять, что вы хотите сделать. зачем такая сложная конструкция, что у вас не работает не понятна.
Если я вызову функцию из таймера, то в ней опять нельзя будет использовать GetTriggerUnit(), а у меня в этой функции объявлен старт ещё одного таймера...
константы варика вроде GetTriggerUnit вызывают и передают аргументы через события см. в теме 7 сообщениетебе уж объясняли в этой теме см в теме 16 сообщение и скачай текстовый файл
ты же сам хранишь этот параметр "True/False" в хэше. И изменяешь в зависимости от срабатывания события вроде юза абилити, таймера истек GetExpiredTimer().
При том, что я в нём каждые 0.05 секунд загружаю булин. А в основной функции написано, что если этот булин тру, то делать дальше.
Зачем тебе создавать лишний таймер, и периодически проверять => лишняя работа. Можно напрямую узнать в хэше. Если значение изменится, ты сам узнаешь через сработки события юза абилити или завершения таймера
function CheckTimer takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer h1 = GetHandleId(t)
local unit caster = LoadUnitHandle(udg_hash,h1,StringHash("caster")) //вызывается функция CheckTimer таймером, то вар константы вроде GetSpellAbilityUnit() не работают. тк завяны на потоки. Поэтому загружаем кастера из хэша, который сохраняю по ключу хэндла таймера t
local integer h2 = GetHandleId(caster) //далее достаем ключ хэндла кастера
local location point = LoadLocationHandle(udg_hash,h2,StringHash("point"))
local boolean check = LoadBoolean(udg_hash,h2,StringHash("check"))
//call SaveInteger(udg_hash,h2,StringHash("h"), h2 ) //не понятное действие
далее 3 варианта: 1)пересохраняем call SaveBoolean(udg_hash,h2,StringHash("check"), false) 2) очищаете ячейку call RemoveSavedHandle(udg_hash,h2,StringHash("check")) 3) по привычке удалить таймер и очистить таблицу по h1 и h2
берем 3 вариант, тк очистим ячейки хэша и удалим таймер.
call DestroyTimer(t)
call FlushChildHashtable(udg_hash,h1)
call FlushChildHashtable(udg_hash,h2)
set caster = null
set point = null
set t = null
endfunction
function Attack takes nothing returns nothing
local unit caster = GetSpellAbilityUnit()
local location point = GetSpellTargetLoc() //для чего точка используется?
local timer t = CreateTimer() //Создаём таймер
local integer h1 = GetHandleId(t)
local integer h2 = GetHandleId(caster)
local boolean check = true
call SaveUnitHandle(udg_hash,h1,StringHash("caster"),caster)
call SaveLocationHandle(udg_hash,h1,StringHash("point"),point) //зачем точку создавать?
call SaveBoolean(udg_hash,h2,StringHash("check"),check)
call TimerStart(t, 1, false, function CheckTimer)
set caster = null
set point = null
set t = null
endfunction
library vectors
struct vector
real x
real y
real z
//Статичный метод создающий вектор, принимает координаты возвращает вектор.
//Вектор - отрезок AB, соединяющий из точки A в точку B. Вектор кроме того имеет направление.
//V = (x, y, z) => казалось храним координаты точки, не совсем точно. Храним отрезок с направлением.
//правильнее V = (Bx-Ax, By-Ay, Bz-Az) => из конца вычитаем начало
//эта функция создаем вектор. создается структура, короче выделяется место под массивы. максимум доступно 8190
//прописываем: local vector v = vector.create(0,0,0) <= координаты
static method create takes real x, real y, real z returns vector
local vector v = vector.allocate() // <= что-то вроде перебора индекса массива
set v.x=x
set v.y=y
set v.z=z
return v //<= возвращает на самом деле индекс, номер структуры
endmethod
//Умножает вектор на какое либо число.
//V = V * r
//если раскрыть:
//set v_x[this]=v_x[this] * r
//set v_y[this]=v_y[this] * r
//set v_z[this]=v_z[this] * r
//пишем: local vector v = vector.create(1,1,1)
//пишем: call v.realmul(2) // <= результат вектор с координатами 2 2 2
method realmul takes real r returns nothing
set .x=.x*r
set .y=.y*r
set .z=.z*r
endmethod
//Модуль вектора - метод возвращающий длину вектора (число всегда >0)
//|V| = sqrt(x*x + y*y + z*z)
//пишем: local vector v = vector.create(0,0,1)
//пишем: local real r = v.getlength() <= результат равен 1
method getlength takes nothing returns real
return SquareRoot(.x*.x+.y*.y+.z*.z)
endmethod
//Устанавливет длину вектора равным 1
//Нормализация — приведение к единичному размеру;
//нормализация в трехмерном пространстве - по сути является масштабированием в куб единичного размера
//Для нормализации вектора нужно каждую компоненту поделить на длину вектора, или умножить инверсию длины на данный вектор.
//V/|V| = (x/|V|, y/|V|, z/|V|) <= короче складываем кажду координату, больше вычислении нужно
//set InvLength = 1/legth <=инверсия, здесь меньше вычислении
method normalize takes nothing returns nothing
local real l = .getlength()
if l>0 then
call .realmul(1/l)
endif
endmethod
//Принимает число. Устанавливает длину вектора равной этому числу.
//похожий метод у функции normalize
//пишем: local vector v = vector.create(54,0,0)
//пишем: call v.setlength(30) <= результат: вектор а равен 30 0 0
method setlength takes real r returns nothing
local real l = .getlength()
if l>0 then
call .realmul(r/l)
endif
endmethod
//Принимает вектор. Возвращает число равное скалярному произведению этих векторов.
//Пусть в этом методе A - первый вектор, B - второй вектор (не путайте, выше был предоставлен вектор AB, сейчас поменял обозначения)
// A*B = Ax*Bx + Ay*By + Az*Bz
//используется часто для вычисления углов между векторами
//пишем: local vector v = vector.create(1,2,3)
//пишем: local vector w = vector.create(1,0,3)
//пишем: local real r = v.scalarmul(w)
//результат равен 10
method scalarmul takes vector v returns real
return .x*v.x+.y*v.y+.z*v.z
endmethod
//Принимает вектор. Устанавливает вызывающий вектор равным сумме самого себя и принятого вектора.
//Пусть в этом методе A - первый вектор, B - второй вектор (не путайте, выше был предоставлен вектор AB, сейчас поменял обозначения)
// Bx= Ax+Bx, By= Ay+By, Bz = Az+Bz <= изменяются параметры вектора B
//пишем: local vector v = vector.create(1,2,3)
//пишем: local vector w = vector.create(1,0,3)
//пишем: local real r = v.vectoradd(w)
//результат: вектор v равен 2 2 6, вектор w не изменился
method vectoradd takes vector v returns nothing
set .x=.x+v.x
set .y=.y+v.y
set .z=.z+v.z
endmethod
//аналогично как и метод vectoradd, только вычитывает
method vectorsub takes vector v returns nothing
set .x=.x-v.x
set .y=.y-v.y
set .z=.z-v.z
endmethod
//Принимает вектор. Устанавливает вызывающий вектор равным векторному произведению самого себя и принятого вектора.
//Пусть в этом методе A - первый вектор, B - второй вектор (не путайте, выше был предоставлен вектор AB, сейчас поменял обозначения)
//Bx= (Ay*Bz - By*Az), By= (Az*Bx - Bz*Ax), Bz = (Ax*By - Bx*Ay)
//пишем: local vector v = vector.create(1,0,0)
//пишем: local vector w = vector.create(0,1,0)
//пишем: local real r = v.vectormul(w)
//результат: вектор v равен 0 0 1, вектор w не изменился
method vectormul takes vector v returns nothing
local real x = .y*v.z-v.y*.z
local real y = .z*v.x-v.z*.x
local real z = .x*v.y-v.x*.y
set .x = x
set .y = y
set .z = z
endmethod
//Принимает вектор. Возвращает вектор равный вызывающему.
//Смысл: эта функция создает копию-вектор, который принимает те же значения что у оригинала
//пишем: local vector v = vector.create(1,0,0)
//пишем: local vector w = vector.clone()
//результат: вектор v равен 1 0 0, вектор w равен 1 0 0
method clone takes nothing returns vector
local vector v=vector.allocate()
set v.x=.x
set v.y=.y
set v.z=.z
return v
endmethod
//Принимает вектор. Устанавливает значение вызывающего вектора равным принятому вектору.
//В отличии от метода clone здесь не создается двойник, у нас уже имеется вектор. Не всегда имеет смысл создавать двойников
//пишем: local vector v = vector.create(1,0,0)
//пишем: local vector w = vector.create(0,1,0)
//пишем: call v.copy(w)
//результат: вектор v равен 0 1 0, вектор w равен 0 1 0
method copy takes vector p returns nothing
set .x=p.x
set .y=p.y
set .z=p.z
endmethod
//Принимает координаты x, y и z. Форсированное изменение координат вектора.
//Изменяет текущий вектор.
//пишем: local vector v = vector.create(1,0,0)
//пишем: call v.change(1,1,1)
//результат: вектор v равен 1 1 1
method change takes real x, real y, real z returns nothing
set .x=x
set .y=y
set .z=z
endmethod
//Принимает вектор. Вычисляет угол между двумя векторами.
//Пусть в этом методе A - первый вектор, B - второй вектор (не путайте, выше был предоставлен вектор AB, сейчас поменял обозначения)
//Вытекает из скалярного произведения AB*Cos(A)
//CosA = AB/|A|*|B|, где AB = ax*bx + ay*by + az*bz и |A| = sqrt(ax*ax + ay*ay + az*az), |B| = sqrt(bx*bx + by*by + bz*bz)
method AngleBetweenVectors takes vector b returns real //в радинах
local real ab =.scalarmul(b)/(.getlength()*b.getlength())
return ab
endmethod
method AngleBetweenVectors2 takes vector b returns real //в градусах
local real ab =.scalarmul(b)/(.getlength()*b.getlength())
return Acos(ab)
endmethod
endstruct
endlibrary
пример движения (для новичка), то же самое что и в статье.
хотя я и сам новичок, тк не каждый день приходиться кодить и писать движения. Мне приходится вспоминать свои шпаргалки, или браться за учебники матана.
ниже представлен пример движения снаряда u от u1 (кастера) до u2 (цели)
local unit u1 = GetTriggerUnit()
local unit u2 = GetSpellTargetUnit()
local real x1 = GetUnitX(u1)
local real y1 = GetUnitY(u1)
local real z1 = GetUnitZ(u1)
local real x2 = GetUnitX(u2)
local real y2 = GetUnitY(u2)
local real z2 = GetUnitZ(u2)
local real x
local real y
local real z
local real facing = GetUnitFacing(u1)
local real apha //угол между точками кастера и цели
local real theta //угол между вектором dz и точкой движения (точнее текущей длиной между точками кастера и цели)
local real dx
local real dy
local real dz
local real dist
local real move_cord = 1000. //move_cord - смещение от начала точки, по-другому можно назвать скоростью speed, если представить окружность то это значение будет радиус-вектором R
if u2 == null then
set x2 = GetSpellTargetX()
set y2 = GetSpellTargetY()
set z2 = GetLocZ(x2,y2)
endif
set dx = (x2-x1)
set dy = (y2-y1)
set dz = (z2-z1)
set dist = SquareRoot( dx*dx + dy*dy )
set alpha = Atan2(dy, dx)
set theta = Atan2(dz, dist)
x = x1 + move_cord * Cos( alpha ) * Sin( theta )
y = y1 + move_cord * Sin( alpha ) * Sin( theta )
z = z1 + move_cord * Cos( theta )
Движение по Z организовывается чуть сложнее, чем в плоскости, из-за особенностей вара:
//инициализация движения
real speed = 1000.0 //скорость движения
//теперь надо преобразовать скорость в вектор движения
real speed_x = speed * Cos(apha) * Sin(theta)
real speed_y = speed * Sin(apha) * Sin(theta)
real speed_z = speed * Cos(theta)
//сохраняем в хеш проекции скорости, и двигаем юнит таймером
//по Z чуть труднее
//не забываем умножать скорость на период таймера
real X = GetUnitX(u) + speed_x * timerPeriod
real Y = GetUnitY(u) + speed_y * timerPeriod
real Z = GetUnitFlyHeight(u) + speed_z * timerPeriod
real land_z = GetLocZ(X,Y) - GetLocZ(GetUnitX(u), GetUnitY(u)) //изменение высот ландшафта между текущей точкой юнита и будущей точкой (X,Y)
SetUnitX(u, X)
SetUnitY(u, Y)
SetUnitFlyHeight(u, Z+land_z, 0)
xgm.guru/p/wc3/183641?postid=343279я собирал кучу наработку движения снарядов. там есть прямые движение по xyz. так вроде недавно видел много наработок и статье по lua
Я только не понимаю: 0 - это значение, с которым мы сохраняем кастера? А если кастеров много, они все будут записываться в значение 0?
parentKey - родительский ключ childKey - младший ключ
ты похоже не понимаешь как работает. хэндл у объектов разный, это просто счетчик объектов. например, создается первый футман ему перечисляют номер 1000 (1000-это условно, просто handle берет большие значения), спавнится второй футман он имеет номер 1001, создается третий футман 1002, создается стрелок 1003, декор 1004 итд. короче у разных кастеров не мб конфликта тк хэндлы разные
конфликты могут быть в коде, если старший и младший ключи совпадают. например 2 разных триггера, короче 2 абилки. Но имеют одинаковые ключи (первый: handle,0 второй: handle,0. Может произойти так что в одном триггере сохранишь, а в каком-нибудь втором из них перезапишешь данные. надо во втором триггере изменить младший ключ. изменить во втором во так: handle,1 - будет совсем другая ячейка)
А как это именно внутри функции с условием написать?
На гуи есть готовое решение. В разделе Boolean => HaveSavedHandle
И что такое число A?
Ну можно числа загружать из хэша
LoadInteger(Hash,id,0)>0 //в разделе integer
LoadReal(Hash,id,0)>0 //в разделе real
Кстати есть вот такая готовая функция BJ, в разделе boolean. не знал что есть
функция
function HaveSavedValue takes integer key, integer valueType, integer missionKey, hashtable table returns boolean
if (valueType == bj_HASHTABLE_BOOLEAN) then
return HaveSavedBoolean(table, missionKey, key)
elseif (valueType == bj_HASHTABLE_INTEGER) then
return HaveSavedInteger(table, missionKey, key)
elseif (valueType == bj_HASHTABLE_REAL) then
return HaveSavedReal(table, missionKey, key)
elseif (valueType == bj_HASHTABLE_STRING) then
return HaveSavedString(table, missionKey, key)
elseif (valueType == bj_HASHTABLE_HANDLE) then
return HaveSavedHandle(table, missionKey, key)
else
// Unrecognized value type - ignore the request.
return false
endif
endfunction
DopaMine, что вы хотите сделать? просто зачем вам хэш?
есть статья
просто для начала нужна ссылка на объект хэндл, чтобы получить GetHandleId(<object>). Или как-то записать или как-то по логике вызывается. Я просто напишу примеры для понимания как это работает. Хэндл этот просто помогает хранить/доставать данные, короче работать с ячейками
пример магазина, также можно сделать склад
как пример на jass
триггер 1 - продаем в магазин
событие - юнит закладывает в лавку (у нас 3 вар переменные: продавец и покупатель, предмет item, который продают в магазин. Эти 3 переменные-константы вызываемые при событии)
допустим мы можем сохранить item в хэш-таблицу по ключам. Это нужно для того, чтобы знать что есть в магазине. Какие предметы хранятся в магазине, в каком слоте, сколько зарядов. Просто нет никаких доп нативок для узнавания, поэтому мы импровизируем, создаем свою базу данных. Этот хэндл сыграл существенную роль
GetHandleId(<покупатель>)
также в хэш можно записать разные данные вроде тип, заряды, номер слота и пр
триггер 2 - выкупаем из магазина (аналогично 3 вар переменные, только роли продавца и покупателя меняются местами)
событие - юнит закладывает из лавки
допустим предмет удаляется из магазина, нам нужно из таблицы в данных магазина удалить этот предмет. с помощью хэндла магазина GetHandleId(продавец). С помощью вар переменной item можно достать тип и др данные хранящие в хэндле GetHandleId(продавец)
ваш случай
А триггера два, так как когда юнит жмёт способность, она сработает только если этот юнит атакован, в противном случае - просто идёт кулдаун. Как это сделать в одном триггере - хз.
Не знаю что хотите сделать. Но примерно догадываюсь, но это можно подкорректировать. Можно в атакующем юните хранить boolean b (да/нет), по хэндлу атакующего сохранять. Этот флаг будет говорить находится ли в кулдауне или нет.
Триггер 1 - при атаке загружаем boolean b по хэндлу атакующего и проверяем. Если boolean b вернет истину, то ваши действия.
Триггер 2 - при активации абилки запускаем таймер. Сохраняем в хэше boolean b = true (истина). Таймер длится столько сколько в кулдауне указано. По истечению таймера boolean b = false (ложь). Можно просто очистить хэш.
еще один чувак, который не умеет выражать свои мысли и что ему надо. Не совсем понятно, что вам нужно.
Если вы хотите знать кто зашел, то можно строкой выводить на экран. Выводите имя юнита. GetUnitName(<unit>) точнее вам будет название типа юнита, как в редакторе назвали юнита так и будет. Например, пехотинец, лучник итд
ID этого юнита(не ID типа юнита, а ID юнита!)
Если вам нужен не ID типа юнит, то что это за ID юнит? мб handle юнита? handle - номер объекта, у разных объектов разные номера. Но счетчики там большие. Есть нативка определения хэндла
GetHandleId(<unit>), которое возвращает целое число integer. короче номер объекта. не только юнита, можно любой наследник-объект хэндла (итем, декор, юниты, группа, олния и пр)
чтобы вывести строку на экран, нужно конвентировать число в строку I2S(<integer>)
на jass функция GetUnitTypeId(<unit>) возвращает id-тип, короче число. К примеру 'hfoo' - равкод футмана. мне лень просто объяснять вот
еще одна функция
GetObjectName(<id-object>) - в эту функцию вписываешь номер, целочисленное число. Короче тип объекта id-object. Это мб ид-юнит, ид-предмет, ид-декор, ид-абилы и др
похожая тема
придется отказаться от порчи. в требованиях пути указано где можно ставить и где нельзя. попробуй отключить требование, те здания нежити строятся на порчи. это из-за больших размеров карты происходит какая ошибка в проверке, даже, если если порча есть.
создай проверку, и искусственно чекай точки при отдаче приказа в точку "строить" и создавай порчу. это самое легкое
keksCsGo777, никак. там у несколько игрушечных абил приказ общий. изменить это никак.
можно через канал+dummy-cast, но визуально вы не увидите как ставите, за вас сделает даймик
создать нестанд картинку, обведя альфа-слойбез прозрачного слоя вокруг картинка получится смазанной, поэтому обязательно нужно края альфа-каналом обработать еще в slk-файле редактировать смотри в Splats\UberSplatData.slk информацию (извлеки эту таблицу из архива игры), там и код и анимация создания и появления, короче настройки указаны в slk. А вот в РО указано в "графика - текстура почвы (ubersplat)"
Либо берешь и заменяешь стандартные уберсплаты, заменяя станд путь. Или берешь slk-таблицу, в ней создаешь новую нестанд уберсплат, новый код и новую импортную картинку. пример
нажми Shift+Enter и пропиши новый код. Например, башня Альянса имеет код HSMA. Можешь сначала в slk-таблице создать QWER, а потом попробовать в башне прописать QWER
мб ошибаюсь, не знаю будет ли работать не стандартный код
юзаем поиск: dummy-cast (есть статья для начинающих)
смотря какие задачи перед вами стоят:
таймер смерти добавляешь на юнита. по истечении которого ваш юнит сам умрет. все так делали. вешали таймер, и юнит умирал после каста.
обычное удаление - это RemoveUnit. Но это мгновенное удаление, и может не успеть каставать. Поэтому нужна задержка вроде таймера смерти
событие какое? мб это вылетает из-за того что пытаешься удалить исследуемого юнита? "исследуемый юнит" - так понимаю, это юнит который завершает исследование, но ты пытаешься удалить его?
еще проверь не приводят ли замена бнитов к фаталу, особенно здания. больше пока не вижу на скрине ничего такого
я хочу упереться в борт, потерять 30% скорости и продолжить движение, но тут я даже не вижу этих бортов
можно навигационную стрелочку над головой сделать, пусть показывает что едешь правильно/не правильно. участки дороги можно поделить на мелкие прямые трассы (если будет крутой поворот, тогда нужно сразу делить тк навигатор сразу в обход к финишу поведет, а надо по дороге ехать. короче дугу на несколько кривых делим), на каждом участке дороги будет места куда надо доехать
стрелочку сделать не трудно и пусть меняет цвет красный: зеленый .
» WarCraft 3 / Бета версия Warcraft III Reforged 1.32
Ред. MpW
» WarCraft 3 / Смена текстуры медведя в игре
Ред. MpW
» WarCraft 3 / Бета версия Warcraft III Reforged 1.32
Ред. MpW
» WarCraft 3 / Бета версия Warcraft III Reforged 1.32
ну и бывает и хуже, у рефордж тоже не идеал. где то старые получше: по звучанию, тембру голоса, и пр
Есть и такие изменения: вот Рохан, к рефорджа спокойный какой то старческий голос, а в старой озвучке: молодой крикливый голос, кричащий вечно спешит куда то
» WarCraft 3 / Событие для способности типа вкл/выкл(жар преисподней)
Ред. MpW
» WarCraft 3 / Удалить сообщение DisplayTimedTextToForce
GetTriggerPlayer - игрок триггера
константа GetLocalPlayer() возвращает локального игрока, у которого запущена игра. Допустим есть 2 игрока, играющие между собой. на машине первого игрока GetLocalPlayer() вернет первого, на машине второго игрока GetLocalPlayer() вернет второго игрока. Вообще между ними должна сихронизация. иначе при неправильном коде при сработке вылетает и все.
Главное просто условие записать. "локал игрок == твой игрок" Поменяй приказ. У канала это возможно. см. ссылка
Ред. MpW
» WarCraft 3 / Загрузка по хэндлу в функцию
см. в теме 7 сообщение тебе уж объясняли в этой теме
см в теме 16 сообщение и скачай текстовый файл
ты же сам хранишь этот параметр "True/False" в хэше. И изменяешь в зависимости от срабатывания события вроде юза абилити, таймера истек GetExpiredTimer(). Зачем тебе создавать лишний таймер, и периодически проверять => лишняя работа. Можно напрямую узнать в хэше. Если значение изменится, ты сам узнаешь через сработки события юза абилити или завершения таймера
» WarCraft 3 / Камень включён
Ред. MpW
» WarCraft 3 / CreateTimer
1)пересохраняем call SaveBoolean(udg_hash,h2,StringHash("check"), false)
2) очищаете ячейку call RemoveSavedHandle(udg_hash,h2,StringHash("check"))
3) по привычке удалить таймер и очистить таблицу по h1 и h2
берем 3 вариант, тк очистим ячейки хэша и удалим таймер.
Ред. MpW
» WarCraft 3 / Движение по 3 ося XYZ
вот статья из вики
ниже представлен пример движения снаряда u от u1 (кастера) до u2 (цели)
Ред. MpW
» WarCraft 3 / Как на Jass'е вернуть уникальное ID юнита и записать в локалку?
childKey - младший ключ
ты похоже не понимаешь как работает. хэндл у объектов разный, это просто счетчик объектов. например, создается первый футман ему перечисляют номер 1000 (1000-это условно, просто handle берет большие значения), спавнится второй футман он имеет номер 1001, создается третий футман 1002, создается стрелок 1003, декор 1004 итд. короче у разных кастеров не мб конфликта тк хэндлы разные
конфликты могут быть в коде, если старший и младший ключи совпадают. например 2 разных триггера, короче 2 абилки. Но имеют одинаковые ключи (первый: handle,0 второй: handle,0. Может произойти так что в одном триггере сохранишь, а в каком-нибудь втором из них перезапишешь данные. надо во втором триггере изменить младший ключ. изменить во втором во так: handle,1 - будет совсем другая ячейка) На гуи есть готовое решение. В разделе Boolean => HaveSavedHandle Ну можно числа загружать из хэша
» WarCraft 3 / Как на Jass'е вернуть уникальное ID юнита и записать в локалку?
проверка хэндла
обычно изначально в ячейках если ничего не записано, то вернет 0 или null
Ред. MpW
» WarCraft 3 / Как на Jass'е вернуть уникальное ID юнита и записать в локалку?
есть статья
просто для начала нужна ссылка на объект хэндл, чтобы получить GetHandleId(<object>). Или как-то записать или как-то по логике вызывается. Я просто напишу примеры для понимания как это работает. Хэндл этот просто помогает хранить/доставать данные, короче работать с ячейками
триггер 1 - продаем в магазин
событие - юнит закладывает в лавку (у нас 3 вар переменные: продавец и покупатель, предмет item, который продают в магазин. Эти 3 переменные-константы вызываемые при событии)
допустим мы можем сохранить item в хэш-таблицу по ключам. Это нужно для того, чтобы знать что есть в магазине. Какие предметы хранятся в магазине, в каком слоте, сколько зарядов. Просто нет никаких доп нативок для узнавания, поэтому мы импровизируем, создаем свою базу данных. Этот хэндл сыграл существенную роль
GetHandleId(<покупатель>)
также в хэш можно записать разные данные вроде тип, заряды, номер слота и пр
событие - юнит закладывает из лавки
допустим предмет удаляется из магазина, нам нужно из таблицы в данных магазина удалить этот предмет. с помощью хэндла магазина GetHandleId(продавец). С помощью вар переменной item можно достать тип и др данные хранящие в хэндле GetHandleId(продавец)
Триггер 2 - при активации абилки запускаем таймер. Сохраняем в хэше boolean b = true (истина). Таймер длится столько сколько в кулдауне указано. По истечению таймера boolean b = false (ложь). Можно просто очистить хэш.
Ред. MpW
» WarCraft 3 / Как на Jass'е вернуть уникальное ID юнита и записать в локалку?
GetHandleId(<unit>), которое возвращает целое число integer. короче номер объекта. не только юнита, можно любой наследник-объект хэндла (итем, декор, юниты, группа, олния и пр)
чтобы вывести строку на экран, нужно конвентировать число в строку I2S(<integer>)
еще одна функция
GetObjectName(<id-object>) - в эту функцию вписываешь номер, целочисленное число. Короче тип объекта id-object. Это мб ид-юнит, ид-предмет, ид-декор, ид-абилы и др
Ред. MpW
» WarCraft 3 / Порча не работает на картах с размером больше 256х256
придется отказаться от порчи. в требованиях пути указано где можно ставить и где нельзя. попробуй отключить требование, те здания нежити строятся на порчи. это из-за больших размеров карты происходит какая ошибка в проверке, даже, если если порча есть.
Ред. MpW
» WarCraft 3 / Иконки "Драгоценные камни"
Ред. MpW
» WarCraft 3 / Проводник по способностям
можно через канал+dummy-cast, но визуально вы не увидите как ставите, за вас сделает даймик
Ред. MpW
» WarCraft 3 / Нестандартные фундаменты
еще в slk-файле редактировать
смотри в Splats\UberSplatData.slk информацию (извлеки эту таблицу из архива игры), там и код и анимация создания и появления, короче настройки указаны в slk. А вот в РО указано в "графика - текстура почвы (ubersplat)"
Либо берешь и заменяешь стандартные уберсплаты, заменяя станд путь. Или берешь slk-таблицу, в ней создаешь новую нестанд уберсплат, новый код и новую импортную картинку. пример мб ошибаюсь, не знаю будет ли работать не стандартный код
Ред. MpW
» WarCraft 3 / Удаление дамми после каста спелла
смотря какие задачи перед вами стоят:
таймер смерти добавляешь на юнита. по истечении которого ваш юнит сам умрет. все так делали. вешали таймер, и юнит умирал после каста.
» Crazy Dwarf Race / Crazy Dwarf Race
Ред. MpW
» WarCraft 3 / Вылетает редактор при изменении тригера.
еще проверь не приводят ли замена бнитов к фаталу, особенно здания. больше пока не вижу на скрине ничего такого
» Crazy Dwarf Race / Crazy Dwarf Race
Ред. MpW
» Crazy Dwarf Race / Crazy Dwarf Race
стрелочку сделать не трудно и пусть меняет цвет красный: зеленый .
Ред. nazarpunk
» WarCraft 3 / [lua] Кастуем все заклинания используя один триггер
Ред. MpW
» WarCraft 3 / [lua] Кастуем все заклинания используя один триггер