Steal nerves #1 - 1 день назад (отредактировано ) 0

» WarCraft 3 / если/то/иначе

что-то не вижу на скрине как вы пытаетесь запихнуть в if/then/else. Почему должен угадывать
Предположение: ошибка - локальные переменные объявляются всегда первыми. Если там будет какое-то другое действие, а объявление локалок ниже, то это ошибка. Ты вперед, наверное, поставил действие "if/then/else", а потом начал объявлять что-то там,
» правильно
local unit u
if (условие) then
	действие
endif
» не правильно
if (условие) then
	local unit u
endif
Локалки вначале функции всегда объявляются. Можете в код конвентировать и посмотреть.
вейты не юзайте лучше, используйте таймер. Он поток паузит, еще работает во время паузы, и не точен .
Steal nerves #2 - 2 дня назад 0
Steal nerves #3 - 3 дня назад (отредактировано ) 0

» WarCraft 3 / Blizzard готовят Producer Update для Warcraft 3

жалко, что нет абилки с зарядами (типа осветительного снаряда или совы, только они вот целевые, и неподходящие. сову например не уберешь и др) +триггеры регулирующие число зарядов. Такой класс был бы. А может быть просто можно было циферки влепить? вспомнил чего не хватало
+камеру прикрепить нормально за спиной как в рпг. нормальную, а не такую, что при повороте камеры в бок, возвращала обратно.
Steal nerves #4 - 3 дня назад (отредактировано ) 0

» WarCraft 3 / Подскажите на тему расходников через руны, стаки, вся фигня

мб Shuriken(it)? в переменной it нет никакого итема, пока что.
поэтому может быть и не проходит норм условие. чтобы там ни было в Shuriken
пример смотри тут
Steal nerves #5 - 4 дня назад (отредактировано ) 1

» WarCraft 3 / Ограничение предметов.

пример_карты
ужас столько тем было на этот вопрос, и статьей. неужели нельзя вбить в поиск
прикреплены файлы
Steal nerves #6 - 4 дня назад (отредактировано ) 4

» WarCraft 3 / Ограничение кол-ва определенного предмета в инвентаре.

ладно циклом пробегай и проверяй
» код
set c = 0 счетчик, считывает кол-во итемов с похожим типом (item being manipulated в расчет не берется)
цикл А от 1 до 6
if тип итема (item being manipulated) РАВНО тип итема (item in slot А) and item being manipulated НЕ РАВНО item in slot А then проверяете
set c = c + 1
endif
конец цикла
if с > 0 then
дропать item being manipulated
endif
или можно вообще было сразу дропнуть прямо в цикле и обойтись без счетчика, так как уже есть такой. и выйти из цикла
мб еще эта поможет это типа классификация, забиваете базу данных, проверяет есть ли такой в бд.
Steal nerves #7 - 4 дня назад (отредактировано ) 0

» WarCraft 3 / Blizzard готовят Producer Update для Warcraft 3

GF RaiseD, конечно же (один скил, или все скилы, предметы)
Steal nerves #8 - 5 дней назад (отредактировано ) 2

» WarCraft 3 / Blizzard готовят Producer Update для Warcraft 3

+ вспомнил баг, в триггерах в классификациях юнита есть "оглушение" (короче stun). И она совсем бесполезна (приходилось бафф проверять). Так понимаю, есть проверки в мем хак (думаю оттуда что-то взяли).
+ Хотелось бы еще молчанки разные (невозможность произносить заклинания, или невозможность юзать скилы и использовать итемы в инвентаре. Есть скилы, но нет таких, которые действуют на одну цель. Там помню винные пары и все. ).
+ задавать время существования баффа
Было бы классно, если в целях абилок и атак было больше всяких целей и классификации.
Steal nerves #9 - 5 дней назад 1

» WarCraft 3 / Смертельный союз + Темный ритуал

вопрос только почему я ставлю галочку "оставить в живых" = урон наносишь ему и себе? в некоторых случаях убиваешь сам себя.
Steal nerves #10 - 6 дней назад 0

» WarCraft 3 / Blizzard готовят Producer Update для Warcraft 3

ScorpioT1000, порядок приказов легко запомнить, проблема в том, что нужно знать, что в данный момент зажато ли было Shift-ом. Без этого ничего нельзя получить, так как мб игрок просто кликает и водит героя, как кореец какой-нибудь. Как это вручную реализовывается?
Steal nerves #11 - 1 неделю назад 6

» WarCraft 3 / Blizzard готовят Producer Update для Warcraft 3

интересно можно ли было бы узнать очередь приказов через Shift?
Steal nerves #12 - 1 неделю назад (отредактировано ) 0

» WarCraft 3 / Способность дропающая все предметы у юнита

нужно задержку делать, хотя бы ноль секунд ставил бы. Машина мгновенно код перерабатывает. Юнит не успевает выполнить приказ, даешь один приказ, даешь тут же второй приказ (перебиваешь первый), даешь третий (перебиваешь второй приказ). И в результате выполнит последний. Юниту нужно время для выполнения приказа. Бывают ситуации (не относится к нашему случаю), если приказ дальше радиуса действия абилки, то нужно ему добежать (приблизиться), то еще нужно эффекты какие-то произвести и др, и ему нужно все на это время тоже потратить. К счастью у нас дроп.
вот карта пример правда. вейт + есть утечки + не расчитана на мультиплеерность
есть система ссылка. В ней никак, помню, не мог реализовать мгновенную продажу всех предметов в инвентаре.
прикреплены файлы
Steal nerves #13 - 1 неделю назад (отредактировано ) 0

» WarCraft 3 / Триггеры

ссылка
В гуи есть блок, называется (в действии, в самом наверху If / Then / Else).
Если условие истинно, то выполняется действие внутри блока. Например, у меня есть патроны (патронов > 0 == истина), то стрелять. Здесь ниже пример вставлен, где логическая равна истине, может и ложью (если ложь, то мы пропустим это действие в блоке и пойдем дальше обрабатывать). специально показал пример.
If Истина then
 //делать действие, стреляем
endif
в jass-е на конце всегда блок закрывают, например поставил endif. Это всегда так. Это не только с if-then-else есть еще блок функции (правда на jass видно), блок цикла, блок цикла группы. Если присмотреться, то в гуи внутри блока можно добавить какое-то действие. читай статьи
Steal nerves #14 - 1 неделю назад (отредактировано ) 0

» WarCraft 3 / Blizzard готовят Producer Update для Warcraft 3

GF RaiseD, не знаю, возможно это оно. Если ты про физ. размер в РО, то что-то не похоже (ноль ставил).
вот ссылка когда пробовал затестить
Steal nerves #15 - 1 неделю назад 0

» WarCraft 3 / Blizzard готовят Producer Update для Warcraft 3

GF RaiseD:
+ еще устанавливать проходимость с настройками (как получается, что у блейда стремительность через юнитов норм проходит, а через горы и деревья блок. в некоторых случаях это то, что нужно (не выбегает через горы и деревья, выглядит как бы естественно). SetUnitPathing не то, так как игнорит все преграды путей
Это перефразируй когда тебя отпустит.
ну имеется в виду, что через юнитов норм должен проходить. Пример способности стремительность. Наверное, там физ. размер стоит на ноль. А вот через деревья или ландшафт не должен. Знаешь, если SetUnitPathing отрубить, то юнит легко забирается по уклонам, например с 1 уровня ландшафта на 2.
не знаю как назвать этот уклон поточнее, поэтому скидываю скрин
прикреплены файлы
Steal nerves #16 - 1 неделю назад (отредактировано ) 3

» WarCraft 3 / С помощью триггеров раздать юнитам предметы

не забудьте проверять есть ли у этих юнитов инвентарь (проверять уровень > 0 или кол-во ячеек > 0), если это надо конечно
Steal nerves #17 - 1 неделю назад (отредактировано ) 2

» WarCraft 3 / Blizzard готовят Producer Update для Warcraft 3

GF RaiseD, кстати, кто-либо упоминал о функциях получения текущего цвета юнита? (по RGB) то же не помешало бы.
+ еще узнавать текущий размер юнита (ширина и длина)
+ еще устанавливать проходимость с настройками (как получается, что у блейда стремительность через юнитов норм проходит, а через горы и деревья блок. в некоторых случаях это то, что нужно (не выбегает через горы и деревья, выглядит как бы естественно). SetUnitPathing не то, так как игнорит все преграды путей
Steal nerves #18 - 2 недели назад (отредактировано ) 2

» WarCraft 3 / Полет снаряда по дуге

Кстати можно двигать так:
» скрины формулы
пример с топорами
движение по эллипсу, Rx и Ry отличаются
есть еще формулы по ссылке и ссылке но здесь больше сложностей
» есть форму скорпа
function geoArc takes real wayAbsolute returns real
    return sin((bj_PI / 2.0) * wayAbsolute)
endfunction

function GeoArcBetweenReal takes real wayMin, real wayMax, real wayNow returns real
    return geoArc((wayNow-wayMin) / (wayMax-wayMin))
endfunction

function GeoArcRelative takes real wayMin, real wayMax, real wayNow, real resultMin, real resultMax returns real
    return (GeoArcBetweenReal(wayMin,wayMax,wayNow) * (resultMax-resultMin)) + resultMin
endfunction
вызываешь GeoArcRelative(тут начало отсчета, тут конец отсчета, тут место где находится сейчас, тут минимальный нужный результат, тут максимальный нужный результат) возвращает значение между последними двумя относительно того, как далеко wayNow переместилась между первыми двумя
вобще это в 2D, а надо в 3D - добавь полярные координаты, или сделай отдельно для каждого измерения...
ну у тебя есть Z допустим пол это 50, потолок (самый верх параболы) - это 300
юнит идет от точки 0 до точки 1000, вот он идет, идет, где он щас находится пусть будет X
set unitZ = GeoArcRelative(0, 1000, X, 50, 300)
wayMin - минимальная расстояние (можно поставить ноль)
wayMax - максимальная точка (ставите нужный размер длины дуги)
wayMin и wayMax образуют отрезок (длину дуги)
wayNow - текущее положение точки
resultMin - минимальная высота
resultMax - максимальная высота
карта
еще есть бросок Tiny из доты и бросок из Пуджа Варс (надыбил на форуме). Код очень отличается от типичной параболы у нас на сайте в алгоритмах, там за основу счетчик берется. Мне понравился бросок из Пуджа Варс. Все эти примеры скинул в карту Только в наработке с Toss Tinny, которую скинул, есть небольшая накладка, там у него два скила (спешил и не посмотрел), и нужно поменять id-приказ у канала, тогда будет все ок (не знаю, почему дал ему вторую, мне казалось крута сравнить, щас не кажется)
прикреплены файлы
Steal nerves #19 - 2 недели назад (отредактировано ) 15

» WarCraft 3 / Blizzard готовят Producer Update для Warcraft 3

Неплохо бы иметь больше настроек у кнопок-пустышек, типа канала. Или что-то похожее. Типа возможность не сбивать приказ (типа безумия), возможность запустить скилл на ходу, возможность вставлять анимацию полета снаряда (не у всех работает, у канала не робит, типа полет ядовитого дротика), не у всех работают баффы (не накидываются), нет пустышек с эффектами. Нет нужных автокастовых способностей-пустышек, работающих в разных условиях (и отслеживания). Конечно, это мечты
Нет двойных способностей (типа нажал "включить щит", отобразилась обратная сторона "выключить щит" - есть конечно аналоги щит defend у пехотинца, уникальности нет никакой, можно взять defend. А если что-то придумать)
Steal nerves #20 - 2 недели назад 0

» WarCraft 3 / Как совершить обход по объекту group?

иметь две группы. Есть группа, которую нужно обработать. Создаете еще одну. По ходу цикла в одну добавляете юнита (сохраняете), а из другой удаляете (чтобы выполнился цикл).
Steal nerves #21 - 2 недели назад (отредактировано ) 4

» WarCraft 3 / ubersplat

Немного не понял где можно в редакторе объектов прописать это. Не видел такого. нельзя кажись. Можно в гуи в редакторе триггеров посмотреть что за текстура (если они есть), но сейчас мы говорим про удар грома, знаю, что она есть в уберсплате
» инструкция
  1. нажимаете "создать уберсплат"
  1. выбираете, смотрите что за текстура (там написано)
  1. можно конвентировать триггеры в код и посмотреть что за текстура (нам нужно взять строку)
Получается "THND"
  1. открываете MPQ master открываешь, в архиве находишь папку splats и оттуда извлекаешь таблицу
  1. в таблице ищешь строчку с названием "THND", записано в ней путь текстуры. Это чтоб не искать текстуры.
Но как писал выше, ищи текстуру по пути replaceable textures/splats
вот там в гуи все ли указаны? неизвестно. Смотрел, что-то в таблице мало текстур (44 шт.). Остальные, что хранятся папке по пути replaceable textures/splats, это рассовые (типа A_OrcUberSplat.blp и B_OrcUberSplat.blp и так далее - не понял что значат, и даже не разбирался, больно надо
можешь попробовать свой сплат сделать. Берешь таблицу, прописываешь новый код, новый путь текстурке и др.
прикреплены файлы
Steal nerves #22 - 2 недели назад 2

» WarCraft 3 / ubersplat

кому интересно, есть такая наработка у нас на форуме ссылка
Steal nerves #23 - 3 недели назад (отредактировано ) 6

» WarCraft 3 / ubersplat

Ну это можно для заклинаний и прочее применить. Да можно и без эффекта. Это типа поверхностные картинки всяких кратеров, поверхностей и прочее. Их можно удалить.
для тех кто не знает, чтобы появились нужно прописать (в разделе триггеры - текстура земли). для замены: лежат по пути replaceable textures/splats
аналогично и с изображением Image (в разделе триггеры - изображение)
долго пробовал создавать, у меня что-то не отображалась ни фига без render always state и rendering state. Вообще-то большинство сплатов, и image могут без rendering state отобразиться. А еще вот с изображением image какие-то траблы. если импортировать в изображение какую-нибудь иконку, то бывает текстура изображения почему то размыта или черные квадраты. Создать легко, но часто не прорисовываются изображения норм, и приходится мучаться с переделками иконок. Поможет статья см. ниже
» список нативок
создать uberspat с настройками (boolean forcePaused, boolean noBirthTime). Что значат эти настройки не знаю.
native CreateUbersplat takes real x, real y, string name, integer red, integer green, integer blue, integer alpha, boolean forcePaused, boolean noBirthTime returns ubersplat
разблокирование для показа самого изображения (типа прорисовывается изображение). Без этой команды бывает не отображает уберсплат. Если поставить false, то изображение пропадает. Зачем тогда нужна команда ShowUbersplat?
native SetUbersplatRenderAlways takes ubersplat whichSplat, boolean flag returns nothing
разблокирование во избежание глюков (не знаю что это значит). Как-то связана с отображением, без этой команды в некоторых случаях, видимо, не работает уберсплат.
native SetUbersplatRender takes ubersplat whichSplat, boolean flag returns nothing
показать/спрятать
native ShowUbersplat takes ubersplat whichSplat, boolean flag returns nothing
уничтожить/удалить
native DestroyUbersplat takes ubersplat whichSplat returns nothing
завершить показ. Короче изображение пропадает. Но чаще всего не сразу. Быстрее было бы спрятать или удалить.
native FinishUbersplat takes ubersplat whichSplat returns nothing
перезапустить (короче снова отобразить). Связано с FinishUbersplat
native ResetUbersplat takes ubersplat whichSplat returns nothing
прикреплены файлы
Steal nerves #24 - 3 недели назад 0
Steal nerves #25 - 3 недели назад (отредактировано ) 0

» WarCraft 3 / Изменение Последователиносте работы цыкла

» вот код
local group = CreateGroup()
local unit e
//выбираете всех юнитов группу g, есть в  комменте (http://xgm.guru/p/wc3/187447?postid=345848#comment10) описание всех выборок, начинающих на GroupEnum..
call GroupEnumUnitsInRange(g, x, y, 400., null)
//цикл
loop
	set e = FirstOfGroup(g)
	exitwhen e == null
	//какое-то действие, что-то делаешь с юнитом e 
	call GroupRemoveUnit(g,e)
endloop
call DestroyGroup(g)
что-то похожее есть вот здесь или тут или тут кому надо найдет на сайте
Steal nerves #26 - 3 недели назад 0

» WarCraft 3 / Не работает IsUnitIllusion

Следует предположение, что как только дамми получает приказ применить способность на основе Предмет:Иллюзии, условие IsUnitIllusion просто не успевает какаим-то образом сделать проверку =/
Почему каким-то?
Proshel_Doty, ну возможно они еще не созданы при касте, поэтому лови через определенное время таймером (0.00 сек или 0.01 и так далее). Лучше проверять событием - юнит вызывает боевую единицу, засовывать в группу и так далее
Steal nerves #27 - 3 недели назад (отредактировано ) 2

» WarCraft 3 / Юнит при приземлении после "превращения" поворачивается в 270

да, есть такое (не 270, а 240). например, у друидов-медведей не меняет угол, а у друидов-воронов меняет. ворон поворачивается до превращения. Как-то только опуститься вниз, то перевоплощается в другую форму. Думал, связано это с абилкой, пробовал другие, одно и тоже. можно периодически таймером заставлять не изменять угол поворота, и он останется таким-же
с чем связано неизвестно и бесполезно думать об этом
вот скинул наработку. это примерно, на скорую руку. вейты и прочее. нужно точное время отсчитать от каста до окончательного поворота (я от балды поставил вейт 1 сек.), на гуи
прикреплены файлы
Steal nerves #28 - 3 недели назад 0

» WarCraft 3 / Юнит при приземлении после "превращения" поворачивается в 270

никто не знает, дружок =) это загадка, которую весь сайт должен отгадать
Steal nerves #29 - 3 недели назад (отредактировано ) 0

» WarCraft 3 / Количество операций в одном потоке

ScopteRectuS, тоже такое делал. Помню, надо было найти площадку для стройки, задавал вопрос, и там перебирал каждую точку loop'ами. Но выяснил, что такую работу до конца не выполняет, обрыв. Приходилось там где есть лупы, отделять, и в другую функцию вставлять эти циклы. чтобы потом отдельный поток создавать через ExcecuteFunc.Только так он работал у меня
Steal nerves #30 - 4 недели назад (отредактировано ) 0

» WarCraft 3 / Полет снаряда по дуге

вот примеры. Ничего нового в них нет. Один пример - код из доты про рексара с топорами, и второй по параболе (там подумал еще и поднимать, и двигать в бок), единственное, что не написал возвращение. Просто лень было.
Darknessay, радиус очень сложно вычислить. Это тебе не окружность или сфера, где идеально круглое. там что вроде овала, эллипса. мб есть какие-то способы, но чтобы сделать = надо знать математику хорошо (там геометрия, тригонометрия, матрица и др)
» раскрыть
радиус можно выяснить по теореме пифагора. Помнишь прямоугольный треугольник. Там есть два катета, и гипотенуза (гипотенуза это и есть радиус). горизонтальный катет = d/2, вертикальный катет = h. И там ищи по теореме пифагора. Зная, значения двух катетов, можно еще и узнать и угол (если он нужен).
прикреплены файлы
Steal nerves #31 - 4 недели назад (отредактировано ) 0

» WarCraft 3 / Полет снаряда по дуге

Darknessay, мб Рексара взломать? пен доту смотри
» код опен дота
// OpenDota 6.41 deprotected by NETRAT and DioD
// inspired by everyone who posted on forum threads and feedback page
// based on OpenDota 6.32b, deprotected by DimonT, NETRAT and TheBloodiest
// http://dimon.xgm.ru/opendota/
// Visit our modmaking community at http://xgm.ru/

// Objects used:
// 'A0O1' = Wild Axes (Beastmaster : Rexxar)
// 'A04R' = Marker (Nether Ward 4,Lightning Bolter,Nether Ward 3,Nether Ward 2,Vengeance Death caster,...)
// 'e01T' = Boomerang
// 'Amrf' = Crow Form (Medivh)

// DEBUG Trigger Number : 34
function WildAxesSpell takes nothing returns boolean
	return GetSpellAbilityId()=='A0O1'
endfunction

function WildAxesTreeCut takes nothing returns nothing
	call KillDestructable(GetEnumDestructable())
endfunction

function WildAxesDamage takes unit pWho,real pxx,real pyy,group pVictims returns nothing
	local group lGroup=CreateGroup()
	local unit lTMP
	local rect lMx=Rect(pxx-150,pyy-150,pxx+150,pyy+150)
	call GroupEnumUnitsInRange(lGroup,pxx,pyy,150,null)
	loop
		set lTMP=FirstOfGroup(lGroup)
		exitwhen lTMP==null
		if(IsUnitInGroup(lTMP,pVictims)==false and IsUnitEnemy(lTMP,GetOwningPlayer(pWho))and IsUnitVisible(lTMP,GetOwningPlayer(pWho)))then
			if(GetUnitAbilityLevel(lTMP,'A04R')!=1 and GetUnitState(lTMP,UNIT_STATE_LIFE)>0 and IsUnitType(lTMP,UNIT_TYPE_STRUCTURE)==false)then
				call GroupAddUnit(pVictims,lTMP)
				call UnitDamageTarget(pWho,lTMP,60+GetUnitAbilityLevel(pWho,'A0O1')*30,true,true,ATTACK_TYPE_NORMAL,DAMAG​E_TYPE_NORMAL,WEAPON_TYPE_METAL_HEAVY_SLICE)
				call AddSpecialEffectTarget("Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl&qu​ot;,lTMP,"overhead")
			endif
		endif
		call GroupRemoveUnit(lGroup,lTMP)
	endloop
	call EnumDestructablesInRect(lMx,null,function WildAxesTreeCut)
	call RemoveRect(lMx)
	call DestroyGroup(lGroup)
endfunction

function WildAxesTimer takes nothing returns nothing
	local string lTable=H2Tx(GetExpiredTimer())
	local unit lAxe=GetUnit(lTable,"Axe")
	local unit lCaster=GetUnit(lTable,"Hero")
	local real lAx=GetReal(lTable,"Ax")
	local real lAy=GetReal(lTable,"Ay")
	local real lCx=GetReal(lTable,"Cx")
	local real lCy=GetReal(lTable,"Cy")
	local real lBx=GetReal(lTable,"Bx")
	local real lBy=GetReal(lTable,"By")
	local real laa=GetReal(lTable,"a")
	local real lbb=1-laa
	local boolean lIsPassed=GetBoolean(lTable,"FirstPass")
	local group lCheckGroup=GetGroup(lTable,"AlreadyDamaged")
	call SetUnitX(lAxe,SafeX(lAx*laa*laa+lBx*2*laa*lbb+lCx*lbb*lbb))
	call SetUnitY(lAxe,SafeY(lAy*laa*laa+lBy*2*laa*lbb+lCy*lbb*lbb))
	call WildAxesDamage(lCaster,GetUnitX(lAxe),GetUnitY(lAxe),lCheckGroup)
	if(lIsPassed)then
		call SetReal(lTable,"a",laa-.02)
	else
		call SetReal(lTable,"a",laa+.02)
		call SetReal(lTable,"Ax",GetUnitX(lCaster))
		call SetReal(lTable,"Ay",GetUnitY(lCaster))
	endif
	if(laa<0 and lIsPassed)then
		call SetBoolean(lTable,"FirstPass",false)
		call SetReal(lTable,"Bx",lAx+300*Cos(Atan2(lCy-lAy,lCx-lAx)+GetReal(lTable,"AngleOffset&qu​ot;)))
		call SetReal(lTable,"By",lAy+300*Sin(Atan2(lCy-lAy,lCx-lAx)+GetReal(lTable,"AngleOffset&qu​ot;)))
	endif
	if(laa>1 and lIsPassed==false)then
		call PauseTimer(GetExpiredTimer())
		call DestroyGroup(lCheckGroup)
		call FastFlush(lTable)
		call RemoveUnit(lAxe)
		call DestroyTimer(GetExpiredTimer())
	endif
endfunction

function WildAxesSettings takes nothing returns nothing
	local unit lCaster=GetTriggerUnit()
	local real lCasterX=GetUnitX(lCaster)
	local real lCasterY=GetUnitY(lCaster)
	local real lTargetX=GetLocationX(GetSpellTargetLoc())
	local real lTargetY=GetLocationY(GetSpellTargetLoc())
	local unit lAxe1=CreateUnit(GetOwningPlayer(lCaster),'e01T',lCasterX,lCasterY,270.)
	local unit lAxe2=CreateUnit(GetOwningPlayer(lCaster),'e01T',lCasterX,lCasterY,270.)
	local string lTable1
	local string lTable2
	local timer lTimer1=CreateTimer()
	local timer lTimer2=CreateTimer()
	if GetSpellTargetUnit()!=null then
		set lTargetX=GetUnitX(GetSpellTargetUnit())
		set lTargetY=GetUnitY(GetSpellTargetUnit())
	endif
	call UnitAddAbility(lAxe1,'Amrf')
	call UnitRemoveAbility(lAxe1,'Amrf')
	call SetUnitFlyHeight(lAxe1,150,0)
	call UnitAddAbility(lAxe2,'Amrf')
	call UnitRemoveAbility(lAxe2,'Amrf')
	call SetUnitFlyHeight(lAxe2,150,0)
	set lTable1=H2Tx(lTimer1)
	call SetHandle(lTable1,"Hero",lCaster)
	call SetHandle(lTable1,"Axe",lAxe1)
	call SetHandle(lTable1,"AlreadyDamaged",CreateGroup())
	call SetReal(lTable1,"Ax",lCasterX)
	call SetReal(lTable1,"Ay",lCasterY)
	call SetReal(lTable1,"Cx",lTargetX)
	call SetReal(lTable1,"Cy",lTargetY)
	call SetReal(lTable1,"Bx",lCasterX+300*Cos(Atan2(lTargetY-lCasterY,lTargetX-lCasterX)+45))
	call SetReal(lTable1,"By",lCasterY+300*Sin(Atan2(lTargetY-lCasterY,lTargetX-lCasterX)+45))
	call SetReal(lTable1,"a",1)
	call SetReal(lTable1,"AngleOffset",-45)
	call SetBoolean(lTable1,"FirstPass",true)
	set lTable2=H2Tx(lTimer2)
	call SetHandle(lTable2,"Hero",lCaster)
	call SetHandle(lTable2,"Axe",lAxe2)
	call SetHandle(lTable2,"AlreadyDamaged",CreateGroup())
	call SetReal(lTable2,"Ax",lCasterX)
	call SetReal(lTable2,"Ay",lCasterY)
	call SetReal(lTable2,"Cx",lTargetX)
	call SetReal(lTable2,"Cy",lTargetY)
	call SetReal(lTable2,"Bx",lCasterX+300*Cos(Atan2(lTargetY-lCasterY,lTargetX-lCasterX)-45))
	call SetReal(lTable2,"By",lCasterY+300*Sin(Atan2(lTargetY-lCasterY,lTargetX-lCasterX)-45))
	call SetReal(lTable2,"a",1)
	call SetReal(lTable2,"AngleOffset",45)
	call SetBoolean(lTable2,"FirstPass",true)
	call TimerStart(lTimer1,.025,true,function WildAxesTimer)
	call TimerStart(lTimer2,.025,true,function WildAxesTimer)
endfunction

function WildAxesInit takes nothing returns nothing
	local trigger ltt=CreateTrigger()
	call TriggerRegisterAnyUnitEventBJ(ltt,EVENT_PLAYER_UNIT_SPELL_EFFECT)
	call TriggerAddCondition(ltt,Condition(function WildAxesSpell))
	call TriggerAddAction(ltt,function WildAxesSettings)
endfunction


function InitTrig_Wild_Axes takes nothing returns nothing
endfunction
» код новой доты
function R92 takes nothing returns boolean
	return GetSpellAbilityId()==1093685041
endfunction

function LWI takes nothing returns boolean
return true
endfunction

function T5I takes destructable d returns boolean
return GetDestructableTypeId(d)==1314157667 or GetDestructableTypeId(d)==1314157687 or GetDestructableTypeId(d)==1096053874 or GetDestructableTypeId(d)==1110454322 or GetDestructableTypeId(d)==1110454323 or GetDestructableTypeId(d)==1110454325
endfunction

function QDI takes nothing returns nothing
if T5I(GetEnumDestructable())and IsDestructableAliveBJ(GetEnumDestructable())then
set JJ=JJ+1
call KillDestructable(GetEnumDestructable())
endif
endfunction

function QEI takes real x,real y,real d returns integer
local rect r=Rect(x-d,y-d,x+d,y+d)
set JJ=0
call EnumDestructablesInRect(r,Condition(function LWI),function QDI)
call RemoveRect(r)
set r=null
return JJ
endfunction



function PAI takes real x1,real y1,real x2,real y2 returns real
return SquareRoot(((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2)))
endfunction





function RGI takes real y returns real
local real RDI=GetRectMinY(bj_mapInitialPlayableArea)+50
if(y<RDI)then
return RDI
endif
set RDI=GetRectMaxY(bj_mapInitialPlayableArea)-50
if(y>RDI)then
return RDI
endif
return y
endfunction

function RCI takes real x returns real
local real RDI=GetRectMinX(bj_mapInitialPlayableArea)+50
if(x<RDI)then
return RDI
endif
set RDI=GetRectMaxX(bj_mapInitialPlayableArea)-50
if(x>RDI)then
return RDI
endif
return x
endfunction

function MCI takes group g returns nothing

local integer i=GetHandleId(g)-UY

if i<0 or i>120 then

	set OJ=true

else

	call GroupClear(g)

	set QY[i]=false

	set IJ=i

endif

endfunction

function RA2 takes unit R7I,real x,real y,group WVO returns nothing
local group GK1=MDI()
local unit V11
call QEI(x,y,150)
call GroupEnumUnitsInRange(GK1,x,y,150,Condition(function LWI))
loop
set V11=FirstOfGroup(GK1)
exitwhen V11==null
if(IsUnitInGroup(V11,WVO)==false and IsUnitEnemy(V11,GetOwningPlayer(R7I)))then
if(GetUnitAbilityLevel(V11,1093678162)!=1 and GetUnitState(V11,UNIT_STATE_LIFE)>0 and IsUnitType(V11,UNIT_TYPE_STRUCTURE)==false)then
call GroupAddUnit(WVO,V11)
call UnitDamageTarget(R7I,V11,60+GetUnitAbilityLevel(R7I,1093685041)*30,true,true,ATTACK_TYPE_NORMAL,DAMA​GE_TYPE_NORMAL,WEAPON_TYPE_METAL_HEAVY_SLICE)
call AddSpecialEffectTarget("Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl&qu​ot;,V11,"overhead")
endif
endif
call GroupRemoveUnit(GK1,V11)
endloop
call MCI(GK1)
endfunction

function RB2 takes nothing returns nothing
local integer MKI=GetHandleId(GetExpiredTimer())
local unit RC2=(LoadUnitHandle(XY,(MKI),(290))) //дайми
local unit N0I=(LoadUnitHandle(XY,(MKI),(14))) //кастер
//координаты кастера
local real Ax=(LoadReal(XY,(MKI),(284)))
local real Ay=(LoadReal(XY,(MKI),(285)))
//координаты цели
local real Cx=(LoadReal(XY,(MKI),(286)))
local real Cy=(LoadReal(XY,(MKI),(287)))

local real Bx=(LoadReal(XY,(MKI),(288)))
local real By=(LoadReal(XY,(MKI),(289)))

local real a=(LoadReal(XY,(MKI),(137)))

local real b=1-a

local boolean RD2=(LoadBoolean(XY,(MKI),(291)))

local group WVO=(LoadGroupHandle(XY,(MKI),(133)))

local real RE2=RMaxBJ(PAI(Ax,Ay,Cx,Cy)/1300,0.4)

call SetUnitX(RC2,RCI(Ax*a*a+Bx*2*a*b+Cx*b*b))
call SetUnitY(RC2,RGI(Ay*a*a+By*2*a*b+Cy*b*b))

call RA2(N0I,GetUnitX(RC2),GetUnitY(RC2),WVO)

if(RD2)then

	call SaveReal(XY,(MKI),(137),((a-.02/RE2)*1.0))

else
	
call SaveReal(XY,(MKI),(137),((a+.02/RE2)*1.0))

	call SaveReal(XY,(MKI),(284),((GetUnitX(N0I))*1.0))

	call SaveReal(XY,(MKI),(285),((GetUnitY(N0I))*1.0))

endif

if(a<0 and RD2)then

	call SaveBoolean(XY,(MKI),(291),(false))

	call SaveReal(XY,(MKI),(288),((Ax+300*Cos(Atan2(Cy-Ay,Cx-Ax)+(LoadReal(XY,(MKI),(292)))))*1.0))

	call SaveReal(XY,(MKI),(289),((Ay+300*Sin(Atan2(Cy-Ay,Cx-Ax)+(LoadReal(XY,(MKI),(292)))))*1.0))

endif

if(a>1 and RD2==false)then

	call PauseTimer(GetExpiredTimer())
	
call MCI(WVO)

	call FlushChildHashtable(XY,(MKI))

	call RemoveUnit(RC2)

	call DestroyTimer(GetExpiredTimer())

endif

endfunction

function LGI takes nothing returns nothing
call DisplayTimedTextToPlayer(GetEnumPlayer(),0,U2,YJ,XJ)
endfunction

function LHI takes force LZI,real KLI,string LVI returns nothing
set XJ=LVI
set YJ=KLI
call ForForce(LZI,function LGI)
endfunction

function MDI takes nothing returns group
local integer i=IJ
loop
	exitwhen i==IJ-1
	if QY[i]==false then		
        set IJ=i+1
        if IJ==120 then
			set IJ=0
        endif
        set QY[i]=true		
        return PY[i]
    endif
	set i=i+1
	if i==120 then
		set i=0
	endif

endloop

call LHI(P2,5.00,"|c00ff0303CRITICAL ERROR: FOUND NO AVAILABLE GROUPS|r")
call LHI(P2,5.00,"|c00ff0303Send this replay to IceFrog@gmail.com|r")
return CreateGroup()

endfunction

function QTI takes unit N0I,integer QRI returns nothing
call UnitAddAbility(N0I,QRI)
call UnitMakeAbilityPermanent(N0I,true,QRI)
endfunction

function RF2 takes nothing returns nothing
local unit R7I=GetTriggerUnit()
//координаты кастера
local real Ax=GetUnitX(R7I)
local real Ay=GetUnitY(R7I)
//координаты цели
local real Cx=GetLocationX(GetSpellTargetLoc())
local real Cy=GetLocationY(GetSpellTargetLoc())
//создать dummy
local unit RG2=CreateUnit(GetOwningPlayer(R7I),1697657172,Ax,Ay,270.0)
local unit RH2=CreateUnit(GetOwningPlayer(R7I),1697657172,Ax,Ay,270.0)
//вводят для хэндлов дайми (это нужно для ключа хэша)
local integer RZ2
local integer RV2
//создаем для каждого дайми таймер
local timer RW2=CreateTimer()
local timer RX2=CreateTimer()

if GetSpellTargetUnit()!=null then
	set Cx=GetUnitX(GetSpellTargetUnit())
    set Cy=GetUnitY(GetSpellTargetUnit())
endif

//добавляет какие-то способности для дайми (видимо дает способность ворона - летать)
call QTI(RG2,1097691750) 
call UnitRemoveAbility(RG2,1097691750)
call SetUnitFlyHeight(RG2,150,0)

call QTI(RH2,1097691750)
call UnitRemoveAbility(RH2,1097691750)
call SetUnitFlyHeight(RH2,150,0)

set RZ2=GetHandleId(RW2) //хэндл таймера
call SaveUnitHandle(XY,(RZ2),(14),(R7I)) //кастер
call SaveUnitHandle(XY,(RZ2),(290),(RG2)) //дайми
call SaveGroupHandle(XY,(RZ2),(133),(MDI())) //добавляет созданную группу, функция MDI какие-то счетчики делает и прочую херню
//сохраняем координаты кастера
call SaveReal(XY,(RZ2),(284),((Ax)*1.0))
call SaveReal(XY,(RZ2),(285),((Ay)*1.0))
//сохраняем координаты цели
call SaveReal(XY,(RZ2),(286),((Cx)*1.0))
call SaveReal(XY,(RZ2),(287),((Cy)*1.0))
//сохраняем 
call SaveReal(XY,(RZ2),(288),((Ax+300*Cos(Atan2(Cy-Ay,Cx-Ax)+45))*1.0))
call SaveReal(XY,(RZ2),(289),((Ay+300*Sin(Atan2(Cy-Ay,Cx-Ax)+45))*1.0))
call SaveReal(XY,(RZ2),(137),((1)*1.0))
call SaveReal(XY,(RZ2),(292),((-45)*1.0))
call SaveBoolean(XY,(RZ2),(291),(true))

set RV2=GetHandleId(RX2)
call SaveUnitHandle(XY,(RV2),(14),(R7I))
call SaveUnitHandle(XY,(RV2),(290),(RH2))
call SaveGroupHandle(XY,(RV2),(133),(MDI()))
call SaveReal(XY,(RV2),(284),((Ax)*1.0))
call SaveReal(XY,(RV2),(285),((Ay)*1.0))
call SaveReal(XY,(RV2),(286),((Cx)*1.0))
call SaveReal(XY,(RV2),(287),((Cy)*1.0))
call SaveReal(XY,(RV2),(288),((Ax+300*Cos(Atan2(Cy-Ay,Cx-Ax)-45))*1.0))
call SaveReal(XY,(RV2),(289),((Ay+300*Sin(Atan2(Cy-Ay,Cx-Ax)-45))*1.0))
call SaveReal(XY,(RV2),(137),((1)*1.0))
call SaveReal(XY,(RV2),(292),((45)*1.0))
call SaveBoolean(XY,(RV2),(291),(true))

call TimerStart(RW2,.025,true,function RB2)
call TimerStart(RX2,.025,true,function RB2)

endfunction

function Q8I takes nothing returns boolean
	return true
endfunction

function Q9I takes trigger t,playerunitevent QAI returns nothing
local integer L9I=0
loop
	call TriggerRegisterPlayerUnitEvent(t,Player(L9I),QAI,Condition(function Q8I))
	set L9I=L9I+1
exitwhen L9I==16
endloop
endfunction

function V51 takes nothing returns nothing
local trigger t=CreateTrigger()
call Q9I(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t,Condition(function R92))
call TriggerAddAction(t,function RF2)
endfunction
в новой доте в коде еще кучу глобальных переменных намешаны. мне лень короч разбираться что это за переменные. завтра подробно рассмотрю этот код рексара. мне интересно как он там так двигается. проще взять код из старой опен доты и переделать, и постоянно сравнить с новым. Практически одинаков
дождись клампа
Погоди, так, момент, как может быть парабола не по Z, если при параболе юнит летит по прямой, только высота меняется, а тут он должен лететь дугой?
можно одновременно две вещи сделать (поворачивать дугой, и поднимать по оси Z), просто не знал, что тебе надо.
прикреплены файлы
Steal nerves #32 - 4 недели назад (отредактировано ) 0

» WarCraft 3 / Полет снаряда по дуге

примерно сделал, Ушло 5-10 часов на это математикой занимался, тригонометрию чутка подучил, пытался вставить и прочее.
угол дуги можно отсчитать если знать расстояние между кастером и целью и высоту дуги.
Парабола не только для прыжков подходит, но и для 2D движения.
Подойдет? время таймера не забудь изменить, просто для себя в качестве проверки делал.
Можно еще через эллипс сделать, но я так и не понял как там. Перечитывал статьи про эллипс, столько времени на эллипс убил.
» раскрыть
Хотел сделать что-то вроде эллипса, используя нашу параболу, Проблема такая, летит плавно. Но эллипс по неведомым причинам становится огромным (юнит частенько за пределы карты вылезает), и поэтому не достигает точки. Проверка не может длину нормально проверить (если задать предел расстояния между кастером и целью 1000, то юнит где-то на половине дуги эллипса останавливается) =( возможно ошибка в моей невнимательности. Поэтому эллипс не смог заюзать
» код
function Trig_Cast_Conditions takes nothing returns boolean
return( GetSpellAbilityId() == 'A000' )
endfunction

function ParabolaZ takes real h, real d, real x returns real
  return (4 * h / d) * (d - x) * (x / d)
endfunction

function Trig_Cast_Actions1 takes nothing returns nothing
//запущенный таймер и его id-хэндл
local timer t = GetExpiredTimer()
local integer id = GetHandleId(t)

local unit dummy = LoadUnitHandle(udg_Hash,id,0) //dummy

local real angle = LoadReal(udg_Hash,id,1) //угол поворота
local real h = LoadReal(udg_Hash,id,2) //высота дуги
local real d1 = LoadReal(udg_Hash,id,3) //длина дуги
local real e = LoadReal(udg_Hash,id,4) 
//координаты кастера = начальная точка дуги A
local real x1 = LoadReal(udg_Hash,id,5) 
local real y1 = LoadReal(udg_Hash,id,6)
//конечная точка дуги A2
local real x2 = LoadReal(udg_Hash,id,7)
local real y2 = LoadReal(udg_Hash,id,8)
//определение длины d2 между dummy и конечной точкой A1
local real dx = x2-GetUnitX(dummy)
local real dy = y2-GetUnitY(dummy)
local real d2 = SquareRoot(dx*dx + dy*dy)

//ввожу переменные для будущих вычислений
local real p //достаю нужную высоту с помощью функции параболы
local real A //угол параболы = не пригодился.
local real D //длина эллипса = не пригодился.
local real x
local real y



//на каждый тик таймера отодвигаем на 50 единиц (можно задать больше или меньше, например 70 или 100 на ваше усмотрение)
//e - пройденная длина от начальной A1 точки дуги, с помощью ее достаем нужную высоту p
set e = e + 50. 
set p = ParabolaZ(h,d1,e)
set A = p/e
set D = SquareRoot(e*e* ((1-Cos(A)*2)/2)+ p*p* ((1+Cos(A)*2)/2))


set x = x1 + (e * Cos(angle) - p * Sin(angle)) //e*Cos(angle+A)
set y = y1 + (e * Sin(angle) + p * Cos(angle)) //p*Sin(angle+A)
call SaveReal(udg_Hash,id,4,e) //расстояние от dummy до конечной точки дуги
if GetRectMinX(bj_mapInitialPlayableArea) < x1 and GetRectMaxX(bj_mapInitialPlayableArea) > x1 and GetRectMinY(bj_mapInitialPlayableArea) < y1 and GetRectMaxY(bj_mapInitialPlayableArea) > y1 then
    call SetUnitX(dummy,x)
    call SetUnitY(dummy,y)
else
    set d2 = 0
endif
call BJDebugMsg("дистанция между точками dummy и конечной точки дуги d: " + R2S(d2))
call BJDebugMsg("мнимая дистанция (пройденный путь от начальной точки дуги) e: " + R2S(e))
call BJDebugMsg("длина элипса D: " + R2S(D))
call BJDebugMsg("угол дуги А: " + R2S(A* bj_RADTODEG))

if d2 <= 50 then
    call PauseTimer(t)
    call DestroyTimer(t)
    call FlushChildHashtable(udg_Hash,id)
endif

set t = null
set dummy = null

endfunction

function Trig_Cast_Actions takes nothing returns nothing
//кастер
local unit u = GetTriggerUnit()
//координаты кастера
local real x1 = GetUnitX(u)
local real y1 = GetUnitY(u)
//угол поворота кастера
local real angle = GetUnitFacing(u) * bj_DEGTORAD
//длина дуги = задаем нужную длину дуги
local real d = 1000.
//высота дуги = задаем нужную высоту дуги
local real h = 300
//координаты конечной точки типа цели или точки. В данном случае, берем точку впереди на d
//Примечание: Если вы берете координаты точки каста, то нужно будет высчитать длину дуги
//У дуги две крайние точки: A1 = точка кастера, A2 = конечная точка
local real x2 = x1 + d * Cos(angle)
local real y2 = y1 + d * Sin(angle)
//рандом определяет по какой траектории дуги будет лететь вправо или влево
local integer Random = GetRandomInt(0,1)
//dummy-юнит, снаряд
local unit dummy = CreateUnit(GetTriggerPlayer(),'ewsp',x1,y1,GetUnitFacing(u))
local timer t = CreateTimer()
local integer id = GetHandleId(t)

if Random == 1 then //Если Random равен единице, то делаем высоту отрицательной. Тогда будет лететь в другую сторону
    set h = h * (-1)
endif

call SaveUnitHandle(udg_Hash,id,0,dummy)
call SaveReal(udg_Hash,id,1,angle)
call SaveReal(udg_Hash,id,2,h)
call SaveReal(udg_Hash,id,3,d)
call SaveReal(udg_Hash,id,4,0) //счетчик. сохраняем ноль. считывает нужное расстояние от начало A1 до конца A2 дуги
call SaveReal(udg_Hash,id,5,x1)
call SaveReal(udg_Hash,id,6,y1)
call SaveReal(udg_Hash,id,7,x2)
call SaveReal(udg_Hash,id,8,y2)

call TimerStart(t,0.4,true,function Trig_Cast_Actions1)

set u = null
set dummy = null
set t = null

endfunction

//===========================================================================
function InitTrig_Cast takes nothing returns nothing
    set gg_trg_Cast = CreateTrigger(  )
    call TriggerRegisterPlayerUnitEventSimple( gg_trg_Cast, Player(0), EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Cast, Condition( function Trig_Cast_Conditions ) )
    call TriggerAddAction( gg_trg_Cast, function Trig_Cast_Actions )
endfunction
Кстати я как всегда немного поспешил, нужно исправить вот тут
» раскрыть
if d2 <= 50 then
    call PauseTimer(t)
    call DestroyTimer(t)
    call FlushChildHashtable(udg_Hash,id)
endif
изменить строчку вместо 50 поставить 150
if d2 <= 150 then
прикреплены файлы
Steal nerves #33 - 4 недели назад 0

» WarCraft 3 / Полет снаряда по дуге

Clamp, тоже не понял, когда мне говорил.
Steal nerves #34 - 4 недели назад (отредактировано ) 0

» WarCraft 3 / Blizzard готовят Producer Update для Warcraft 3

вот я бы заплатил бы эту "злую" тысячу
тоже купил бы. Проблема еще в том, что я уже практически не играю в варик, только ради редактора сижу маленько. Что-то делаю, для своей карты. И пока ни разу не выпустил карты....медленно делаю, 5 раз удалял карты до ... Necris делаю, наполеоновские планы насчет нее. Мне нравится идея, но сама карта надоела (сырая), требует скорейшего добавления чего нового. Если это будет в редакторе, то это упростит, этого не хватало в карте
Steal nerves #35 - 4 недели назад (отредактировано ) 0

» WarCraft 3 / Как на Jass быстро посчитать количество боевых единиц?

Есть ли возможность сделать то же без перебора группы?
Нативки такой не видел, нет такой. Есть близзардская Bj-функция CountUnitsInGroup, там перебираем всех и складываем. И нативку GetPlayerStructureCount, показывающую, видимо, кол-во здании
отслеживать появление и исчезновение юнитов с карты с помощью счетчика. При появлении +1, при исчезновении -1. Нужно продумать все факторы: например, юнит красного игрока (-1) перешел на сторону синего игрока (+1) (короче смена хозяина). При событии юнит входит в зону может отслеживать москитов, призывников, что может не всегда нужно. Труднее отследить исчезновение, ведь неизвестно, что вам нужно? только живые? смерть отслеживанием событием юнит умирает (-1). Но этот труп можно воскресить (+1). Если нужно отследить исчезновение трупа юзаем (событие - юнит вышел из региона).
Знаю может быть муторным делом, но если проработать, то не нужно циклом будет делать. Сразу из переменной доставать значение будешь. Либо с группой (Bj-функция CountUnitsInGroup или loop с FirstOfGroup, по-другому никак.
Но у тебя BJ-функция GetUnitsInRectOfPlayer утекает =(( и группой в конце не удаляем
Steal nerves #36 - 4 недели назад 0

» WarCraft 3 / Атака мульти-шот (атака перед лицом) - нужна формула

Мои скиллы не действуют на всю карту, но я должен на будущее знать, будет ли это работать, если прописать радиус меньше дальности скилла. Получается можно удалить строку, отвечающую за радиус?
Тогда да.
Steal nerves #37 - 4 недели назад (отредактировано ) 3

» WarCraft 3 / Функция проверки количества предметов по области

что тут не понятного. ну ты берешь все итемы в области с помощью Pick every item in ... и начинаешь перебирать. Это обычный же цикл. Как это работает? Эта команда Pick every item in ... - цикл, берет все предметы, затем берет один предмет в переменную Picked Item, что-то с ним делаем, Потом берет второй в переменную Picked Item, и также что-то делаем с этим предметом, и так далее. Но можно внутри этого цикла счетчик намутить. целочисленная переменная count - счетчик. Если у тебя 5 предметов, то можешь 5 действий совершить, короче будет 5 раз прибавлять число в count +1.
Честно, как-то лень объяснять. Если надо, проверить тип. То можно фильтр вставить с проверкой (типа matching item == цветок) или внутри вставить конструкцию if then endif с проверкой типа (Picked item == цветок). В фильтрах используют переменные matching item а в циклах Picked item

С рунами, кстати, есть проблема. Это всякие монетки, книжки, зведолисты и прочее. Когда ты подбираешь, они исчезают, короче ничего в инвентарь себе не положишь. Но на карте эти руны остаются, и поэтому счетчик будет прибавлять и их. Из-за чего будет неправильное количество отображать. Есть даже статья
Чтобы такого не было, при подборе удаляйте руны (они ведь исчезают)
прикреплены файлы
Steal nerves #38 - 4 недели назад 0

» WarCraft 3 / Blizzard готовят Producer Update для Warcraft 3

классно, если \то бкдет так
Steal nerves #39 - 4 недели назад (отредактировано ) 2
Steal nerves #40 - 4 недели назад (отредактировано ) 0

» WarCraft 3 / Атака мульти-шот (атака перед лицом) - нужна формула

» много букв
Так для "не смотрит" нужно чтобы юнит попал в большой промежуток?
да, тебе выше скрин даже нарисовал. в твоем случае, как определить видит ли цель кастера, то очень подойдет. для твоего скила "удар в спину". Есть другие примеры, может они то тебе подойдут. Загляни на хабр по ссылке, там точь твой вариант, описывают пример про стражника (если не понятно, смотри у меня скалярные векторы в комменте 6, 7). Конечно, тебе немного переделать надо будет, вместо кастера цель.
Если способность, скажем, через всю карту используется, а тут указывается радиус - если кастер будет за радиусом, что тогда?
если ты про молнии, то тут у меня никакого ограничительного радиуса нет. Есть радиус круга = 800, но это чисто для молнии, не стал молнии растягивать на всю карту.
В первом случае, работы со многими юнитами включает с группой, там есть ограничение радиуса - сам радиус. Когда ты пикаешь вокруг юнитов в группу, есть функции, которые выбирают всех вокруг точки с радиусом. Вот это я и использовал. Если надо убрать ограничение, используй другие функции пика на всю карту, или ставь радиус 99999
В случае, с треугольником. Можно, вместо треугольника вставлять прямоугольник =)
Во втором случае, там с одним юнитом (не работаю с группой). Коммент 7 скинул пример. Там нет ограничения, и можно на всю карту. Есть надо ограничить, тогда надо еще проверять расстояние между двумя юнитами. Если расстояние между двумя юнитами меньше 800, то делать ...
прикреплены файлы
Steal nerves #41 - 1 месяц назад (отредактировано ) 0

» WarCraft 3 / Атака мульти-шот (атака перед лицом) - нужна формула

Обзор_в_180_градусов сделано для новичков
На основе взяты выше перечисленные примеры. Можете проверить стоит ли впереди или нет.
Кстати, формула Warden работает не так как хотелось бы. Тестировал. И выяснил, что работает если обзор не слишком большой ( angle < 180, если хотите 180 тогда придется ставить приблизительно 179). Если слишком большой, то не будет работать.
Короче тут формула берет минимальный промежуток между углами, а не большой. Пример на скрине
А так все в норме
Еще не забудьте поставить вместо udg_Target переменную GetSpellTargetUnit()
прикреплены файлы
Steal nerves #42 - 1 месяц назад 0

» WarCraft 3 / Какая то хрень с ифами :(

наброски
скидывал тебе это, что не помогло?
и проверяй дебагом, работает = не работает.
Steal nerves #43 - 1 месяц назад (отредактировано ) 4

» WarCraft 3 / Какой должна быть сборка wc3, чтобы делать карту в 2к18?

quq_CCCP, тогда библиотеку всех функции вшить в jngp, включая RenderEdge. Сам хотел попробовать мемхак, так лень разбираться, что надо делать "чтобы это заработало", и не знание чего не дало запустить (обычный мемхак ладно, а RenderEdge...)
Steal nerves #44 - 1 месяц назад (отредактировано ) 0

» WarCraft 3 / Как определить, находится ли в процессе постройки/улучшения здан

как сказал pro100master,
Событие юнит начинает строительство
здание, установлено. Но нужно до конца достроить = (сохраняем true)

Событие юнит прекращает строительство
прервано строительство через кнопку отмена = (сохраняем false)

Событие юнит завершает строительство
здание построенно (сохраняем false)

Событие юнит умирает = с проверкой что это здание и строилось ли оно = (сохраняем ffalse)

true/false - установка в логическую переменную. True говорит о том, что здание строится, а false нет.
можно использовать хэндл + хэш или массивы + цикл для хранения
проще простого, с улучшением здания тоже самое посмотри в гуи - там события про апгрейды (начинает улучшение/прерывает улучшение/ завершает улучшение)
Steal nerves #45 - 1 месяц назад (отредактировано ) 0

» WarCraft 3 / Заставить ИИ юзать Морф

Этого никто не знает. У меня вот ИИ-боты сами новые предметы не могут купить, пока не положишь. Некоторые даже не принимает и продает/выбрасывает (оказывается есть типы итемов, и итемы, которые сделаны на этой основе, ИИ заставляет продавать. Брал другой подходящий тип, который бот не продаст, и им же заменял, или на его основе создавал новый).
не пробовали на триггерах ИИ написать. Это правда может быть сложнее. Щас пробую со системой строительства намутить, пробую полную ветку здании строить. Сами строят. Можно даже отойти чай пить, пока ваши юниты строят. Со строительством может и прокатит, а вот с войсками? Там трудного ничего нет. Нанял, накопил войско. Мне пока не хватает знании, так как классический вар мало играю. Не знаю каких юнитов нужно нанимать и в каких количества, там порядок. В битве какие заклинания применять и прочее? Это оказалось сложнее, много всего
Steal nerves #46 - 1 месяц назад (отредактировано ) 2

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

вот 2, 3, 4 варианты точно подойдут
прочитай второй вариант почему это происходит. Тоже делал как ты.
Steal nerves #47 - 1 месяц назад (отредактировано ) 5

» WarCraft 3 / Подземелья Альянса

Заметил не предусмотренность: когда герой подбирает лук и юзает его - он морфится (превращается) в лучника. А когда умирает в этой форме (в форме лучника), он дропает лук и прочие вещички. Но когда воскрешается, то воскрешается в форме лучника. Если "снять экипировку" (так понимаю морф в обычного), то в инвентаре снова появляется лук. Откуда у него лук, если дропнул при смерти
Хотел бы отметить, что тут пищу очень сложно добыть в начале. Это нужно монстров убивать, так понимаю. А вот в конце кучу монстров вылезет, что в таком хаосе трудно защититься, и все мои юниты по сторонам разбегаются мочить крипов, И "орчиха" тут одна на всех?)
Герой развивается только до 5 уровня на "нейтральных" крипах =(( карта немного скучноватая, сыровато
Steal nerves #48 - 1 месяц назад 0

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

вот еще карта с дебагом. слегка доработана
прикреплены файлы
Steal nerves #49 - 1 месяц назад (отредактировано ) 3

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

возможно дебагом
но для разъяснения стоит посмотреть тут
при событии юнит начинает подготовку тренируемого юнита нет, но можно выявить его тип id с помощью trained unit-type.
прикреплены файлы
Steal nerves #50 - 1 месяц назад (отредактировано ) 0

» 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 и проверить без него как работает, просто в этой функции очень много чего напихано, возможно какой-то элемент включает (переменная какая-нибудь)
Еще если союзник ливает, то делай его врагом. И его войска отдаешь себе и все.