Помогите понять в чем проблема, пожалуйста -.-
Снаряд создается с небольшим смещением от героя(правее или левее) и летит по дуге в точку каста.
Смещение = 45 либо -45(рандомно), это же и поворот снаряда исходный.
По формуле мана снаряда устанавливается как = значение, которое должно вычитаться от его текущего поворота, чтобы он собственно летел по дуге, поворачиваясь.
Так вот, почему то финальный угол, который должен быть равен +-90(типа полный поворот снаряда к концу пути = дуга), в итоге равняется 115(где то при 1000 расстояния), а сам снаряд, кажется, долетает расстояние до точки каста, но не формирует полную дугу - чем дальше точка каста. Т.е. он умирает левее или правее точки каста(на глаз, где то на 250-500 от точки каста, при расстоянии в 2000).
Я думаю дело в неверных расчетах с 3.14, но что не так?
Запуск:
Движение(каждые 0.03):

Принятый ответ

Кстати можно двигать так:
скрины формулы
пример с топорами
движение по эллипсу, 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-приказ у канала, тогда будет все ок (не знаю, почему дал ему вторую, мне казалось крута сравнить, щас не кажется)

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
0
19
6 лет назад
0
pro100master:
Но я же не об этом задал вопрос :\
0
23
6 лет назад
0
Darknessay, единсвеный если ты учил геометрия то изи решения
3
30
6 лет назад
3
Смещение = 45 либо -45, это же и поворот снаряда исходный.
Что это значит? Ты уравниваешь 45 единиц длинны и 45 градусов поворота?
Лучше нарисуй схему с указанием всех углов и зависимостей величин, мб и сам решишь в процессе.
0
27
6 лет назад
0
Clamp, тоже не понял, когда мне говорил.
0
19
6 лет назад
Отредактирован Darknessay
0
Clamp:
Поясню:
1- Берется угол АБ( от кастера к таргету)
2- Под углом АБ+45, смещенно на 50 ед. расстояния создается снаряд(С). Снаряд создается с поворотом ЛИЦА = СБ+45 сразу - для удобства, потому что я понимаю, что иначе угол будет не +45.
Так что про угол АБ забываем, чтобы не запутываться. Дальше используем только СБ.
3- Снаряд стоит в точке С, лицом повернут по углу СБ+45.
4- Снаряд начинает двигаться в направлении собственного лица. Каждый тик таймера 0.03, снаряд сдвигается на 70 ед. и должен постоянно поворачивать на N угла(поворота) для того, чтобы его траектория образовала дугу.

Нужно вычислить 2 значения:
1 - реал, который будет отниматься от угла поворота снаряда каждый тик таймера, для того чтобы снаряд летел по дуге.
2 - реал времени, который понадобится снаряду для того, чтобы долететь до точки Б по дуге.
ДА ЧТО ЗА?
Не могу новую картинку прикрепить к тому комменту -_-
Короче да, мне нужна кушка Дианы. Только я не помню, оно летит в точку каста, или там фикс. расстояние? Вроде в точку каста. Если да, то да, кушка Дианы.
Разве что, у меня снаряд создается не в самом герое, а чуть рядом, но мы всё равно начинаем считать всю фигню относительно позиции снаряда(и угла СБ соответственно), а не относительно АБ.

Блин, вот я гомункул. "Дуга, которая должна образоваться" - она, конечно же, не между АБ, а между СБ должна образоваться такой формы, ибо АБ уже не учитывается после спавна снаряда. Просто в паинте я не смог бы "наклонить" сплюснутое кольцо

Если честно, то я уже запарился это обьяснять, ибо не знаю как еще проще обьяснить:
(Предыдущие слова не учитывайте, по новой)
Снаряд вылетает под углом АБ+45, за каждый тик таймера должен поворачивать(угол его поворота должен отниматься), чтобы в конце пути он ударился в точку Б(т.е. его угол ПОВОРОТА в конце должен получиться АБ-45).
Получается, нам нужно вычислить время, за которое снаряд пролетает от А до Б >>ПО ДУГЕ<<(дуга длиннее прямого полета, т.е. и времени чуть больше), потом на основе этого времени выдать снаряду лайфтаймер и получить как раз таки значение угла, которое будет отниматься для образования самой дуги в полете.
Загруженные файлы
2
27
6 лет назад
Отредактирован MpW
2
примерно сделал, Ушло 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
Загруженные файлы
0
23
6 лет назад
0
Опен дота и узнай код рексара который кидает топором вот там и бери =)
0
19
6 лет назад
0
Steal nerves:
Теперь и мне придется 5-10 часов читать про параболу, чтобы применить твой код, ибо твой код самобытен, а мне нужно встроить всё в систему)
Погоди, так, момент, как может быть парабола не по Z, если при параболе юнит летит по прямой, только высота меняется, а тут он должен лететь дугой?
Получается нужно даммика по прямой запускать, а юнита двигать относительно даммика?
0
27
6 лет назад
Отредактирован MpW
0
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,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_METAL_HEAVY_SLICE)
				call AddSpecialEffectTarget("Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl",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")))
		call SetReal(lTable,"By",lAy+300*Sin(Atan2(lCy-lAy,lCx-lAx)+GetReal(lTable,"AngleOffset")))
	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,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_METAL_HEAVY_SLICE)
call AddSpecialEffectTarget("Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl",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), просто не знал, что тебе надо.
Загруженные файлы
0
30
6 лет назад
0
Почему ты называешь вектора углами?
0
19
6 лет назад
Отредактирован Darknessay
0
Clamp:
Почему ты называешь вектора углами?
Потому что в варе это называется "угол поворота"(facing angle) - поворот юнита(лицом) в направлени 0-360 градусов.
Я не силен в терминологии. Вектор = направление, верно?

Вы не могли бы еще сюда заглянуть, ребят?
Я подожду разбор кода топоров от Steal Nerves, но пока что забил и кидаю снаряд по прямой+парабола.
Если у меня получится потом раздуплиться в топорах - сделаю дугу, но это мой загон, не принципиально, а вот момент в вопросе выше - вполне себе важная штука(например, герой должен разбрасывать кольцом вокруг себя 8 снарядов, каждый снаряд должен лететь от героя по параболе(типа он их подкинул ,а потом они падают). их исх. высота = 125, и эту высоту я сниму дополнительным таймером, пока они будут лететь, но эта парабола фиксирует высоту и снаряды сразу перемещаются в Z=0.00, а потом от 0 делают свою параболу - ну, а нужно чтобы они стартовали у него над головой, на высоте 125. надеюсь вы поняли.)
Там в вопросе я написал, что мне нужно просто перенастроить эту параболу таким образом, чтобы она не фиксировала высоту юнита, а прибавляла/убавляла, не перебивая собой другие изменения высоты(например, если подкинуть этого же юнита повторно этой функцией). Полагаю, что это всё таки возможно, но там vJass структура+муи, а с моими гуишными знаниями жасса, я боюсь даже пробовать там что то менять)
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.