Добавлен rsfghd,
опубликован
пример движения по безье (без лишней воды), для пеших и летающих юнитов
код
globals
unit target
real distance
real startx
real starty
real startz
real midx
real midy
real midz
real endx
real endy
real endz
real time
real maxTime = 2.00
real timerPeriodic = 0.01
location LFZ = Location( 0.00, 0.00 )
endglobals
function GetLocZ takes real x, real y returns real
call MoveLocation( LFZ, x, y )
return GetLocationZ( LFZ )
endfunction
function move takes nothing returns nothing
local real a1 = startx
local real b1 = 2.00 * (midx - startx)
local real c1 = startx - 2.00 * midx + endx
local real a2 = starty
local real b2 = 2.00 * (midy - starty)
local real c2 = starty - 2.00 * midy + endy
local real a3 = startz
local real b3 = 2.00 * (midz - startz)
local real c3 = startz - 2.00 * midz + endz
local real x = a1 + (b1 + c1 * time) * time
local real y = a2 + (b2 + c2 * time) * time
local real z = a3 + (b3 + c3 * time) * time
set time = time + ( timerPeriodic / maxTime )
if time > 1.00 then
call PauseTimer( GetExpiredTimer( ) )
call DestroyTimer( GetExpiredTimer( ) )
endif
call SetUnitX( target, x )
call SetUnitY( target, y )
if not IsUnitType( target, UNIT_TYPE_FLYING ) then
call SetUnitFlyHeight( target, z - GetLocZ( x, y ), 0.00 )
else
if GetLocZ( x, y ) < 0.00 then
call SetUnitFlyHeight( target, z, 0.00 )
else
call SetUnitFlyHeight( target, z - GetLocZ( x, y ), 0.00 )
endif
endif
endfunction
function Trig_Attack_Actions takes nothing returns nothing
local real a
set target = GetTriggerUnit( )
if not IsUnitType( target, UNIT_TYPE_FLYING ) then
set distance = 400.00
set startx = GetUnitX( target )
set starty = GetUnitY( target )
set startz = GetLocZ( startx, starty )
set a = Atan2( starty - GetUnitY( GetAttacker( ) ), startx - GetUnitX( GetAttacker( ) ) )
set midx = startx + distance / 2.00 * Cos( a )
set midy = starty + distance / 2.00 * Sin( a )
set midz = GetLocZ( midx, midy )
if midz < 0.00 then
set midz = -midz
endif
set endx = startx + distance * Cos( a )
set endy = starty + distance * Sin( a )
set endz = GetLocZ( endx, endy )
if startz < endz then
set midz = midz + endz
else
set midz = midz + startz
endif
set midz = midz + 200.00
set time = 0.00
call UnitAddAbility( target, 'Arav' )
call UnitRemoveAbility( target, 'Arav' )
call TimerStart( CreateTimer( ), timerPeriodic, true, function move )
else // для летающих (flying)
set target = GetTriggerUnit( )
set distance = 400.00
set startx = GetUnitX( target )
set starty = GetUnitY( target )
set startz = GetLocZ( startx, starty )
if startz < 0.00 then
set startz = 0.00
endif
set startz = startz + GetUnitFlyHeight( target )
set a = Atan2( starty - GetUnitY( GetAttacker( ) ), startx - GetUnitX( GetAttacker( ) ) )
set midx = startx + distance / 2.00 * Cos( a )
set midy = starty + distance / 2.00 * Sin( a )
set midz = GetLocZ( midx, midy )
if midz < 0.00 then
set midz = 0.00
endif
set midz = midz + GetUnitFlyHeight( target )
set endx = startx + distance * Cos( a )
set endy = starty + distance * Sin( a )
set endz = GetLocZ( endx, endy )
if endz < 0.00 then
set endz = 0.00
endif
set endz = endz + GetUnitFlyHeight( target )
if startz < endz then
set midz = midz + endz
else
set midz = midz + startz
endif
set midz = midz + 200.00
set time = 0.00
call UnitAddAbility( target, 'Arav' )
call UnitRemoveAbility( target, 'Arav' )
call TimerStart( CreateTimer( ), timerPeriodic, true, function move )
endif
endfunction
//===========================================================================
function InitTrig_Attack takes nothing returns nothing
set gg_trg_Attack = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Attack, EVENT_PLAYER_UNIT_ATTACKED )
call TriggerAddAction( gg_trg_Attack, function Trig_Attack_Actions )
endfunction
возможности кривой не заканчиваются на этой убогой параболе само собой
следующая функция:
function BezierCurvePow2_xyz_xyz_xyz(x, y, z, x1, y1, z1, x2, y2, z2, time)
local a1 = x
local b1 = 2 * (x1 - x)
local c1 = x - 2 * x1 + x2
local a2 = y
local b2 = 2 * (y1 - y)
local c2 = y - 2 * y1 + y2
local a3 = z
local b3 = 2 * (z1 - z)
local c3 = z - 2 * z1 + z2
local x = a1 + (b1 + c1 * time) * time
local y = a2 + (b2 + c2 * time) * time
local z = a3 + (b3 + c3 * time) * time
return x, y, z
end
принимает несколько точек ( начальная, средняя и конечная ), а так же время, которое нужно конвертировать в соотношении до 1 ( т.е. time += timerPeriodic / maxTime )
я думаю уже понятно что с ней можно делать
от Hate
и от меня:
код
library SpellCastLib
globals
timer TempTimer = CreateTimer( )
real timerPeriodic = 0.01
integer max = 0
unit array dummy
real array startx
real array starty
real array startz
real array midx
real array midy
real array midz
real array endx
real array endy
real array endz
real array time
real array maxTime
location LFZ = Location( 0.00, 0.00 )
endglobals
function GetLocZ takes real x, real y returns real
call MoveLocation( LFZ, x, y )
return GetLocationZ( LFZ )
endfunction
function move takes nothing returns nothing
local real x
local real y
local real z
local integer i
set i = 1
loop
set x = startx[i] + ( ( 2.00 * ( midx[i] - startx[i] ) ) + ( startx[i] - 2.00 * midx[i] + endx[i] ) * time[i] ) * time[i]
set y = starty[i] + ( ( 2.00 * ( midy[i] - starty[i] ) ) + ( starty[i] - 2.00 * midy[i] + endy[i] ) * time[i] ) * time[i]
set z = startz[i] + ( ( 2.00 * ( midz[i] - startz[i] ) ) + ( startz[i] - 2.00 * midz[i] + endz[i] ) * time[i] ) * time[i]
call SetUnitX( dummy[i], x )
call SetUnitY( dummy[i], y )
call SetUnitFlyHeight( dummy[i], z - GetLocZ( x, y ), 0.00 )
set time[i] = time[i] + timerPeriodic / maxTime[i]
if time[i] >= 1.00 then
call KillUnit( dummy[i] )
set dummy[i] = dummy[max]
set startx[i] = startx[max]
set starty[i] = starty[max]
set startz[i] = startz[max]
set endx[i] = endx[max]
set endy[i] = endy[max]
set endz[i] = endz[max]
set midx[i] = midx[max]
set midy[i] = midy[max]
set midz[i] = midz[max]
set time[i] = time[max]
set maxTime[i] = maxTime[max]
set i = i - 1
set max = max - 1
if max <= 0 then
call PauseTimer( TempTimer )
endif
endif
set i = i + 1
exitwhen i > max
endloop
endfunction
function Trig_SpellCast_Actions takes nothing returns nothing
local unit caster = GetTriggerUnit( )
local real x = GetSpellTargetX( )
local real y = GetSpellTargetY( )
local real angle
local real distance
local integer i
set bj_groupEnumOwningPlayer = GetOwningPlayer( caster )
set i = 1
loop
set max = max + 1
set startx[max] = GetUnitX( caster )
set starty[max] = GetUnitY( caster )
set startz[max] = GetLocZ( startx[max], starty[max] ) + 50.00
set dummy[max] = CreateUnit( bj_groupEnumOwningPlayer, 'u000', startx[max], starty[max], GetRandomReal( 0.00, 360.00 ) )
call UnitAddAbility( dummy[max], 'Arav' )
call UnitRemoveAbility( dummy[max], 'Arav' )
call SetUnitPathing( dummy[max], false )
call SetUnitX( dummy[max], startx[max] )
call SetUnitY( dummy[max], starty[max] )
call SetUnitFlyHeight( dummy[max], startz[max], 0.00 )
set endx[max] = x + GetRandomReal( -250.00, 250.00 ) * Cos( GetRandomReal( 0.00, 360.00 ) * bj_DEGTORAD )
set endy[max] = y + GetRandomReal( -250.00, 250.00 ) * Sin( GetRandomReal( 0.00, 360.00 ) * bj_DEGTORAD )
set endz[max] = GetLocZ( endx[max], endy[max] )
set angle = Atan2( endy[max] - starty[max], endx[max] - startx[max] )
set distance = SquareRoot( ( endx[max] - startx[max] ) * ( endx[max] - startx[max] ) + ( endy[max] - starty[max] ) * ( endy[max] - starty[max] ) )
set midx[max] = startx[max] + ( distance / 2 ) * Cos( angle + GetRandomReal( -90.00, 90.00 ) * bj_DEGTORAD )
set midy[max] = starty[max] + ( distance / 2 ) * Sin( angle + GetRandomReal( -90.00, 90.00 ) * bj_DEGTORAD )
set midz[max] = GetLocZ( midx[max], midy[max] )
if startz[max] < endz[max] then
set midz[max] = midz[max] + endz[max]
else
set midz[max] = midz[max] + startz[max]
endif
set midz[max] = midz[max] + distance
set time[max] = 0.00
set maxTime[max] = distance * ( timerPeriodic / 2.00 )
if max == 1 then
call TimerStart( TempTimer, timerPeriodic, true, function move )
endif
set i = i + 1
exitwhen i > 10
call TriggerSleepAction( 0.00 )
endloop
set caster = null
endfunction
function Trig_SpellCast_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A000'
endfunction
endlibrary
//===========================================================================
function InitTrig_SpellCast takes nothing returns nothing
set gg_trg_SpellCast = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_SpellCast, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_SpellCast, Condition( function Trig_SpellCast_Conditions ) )
call TriggerAddAction( gg_trg_SpellCast, function Trig_SpellCast_Actions )
endfunction
спасибо N1ghtSiren и Hate
`
ОЖИДАНИЕ РЕКЛАМЫ...
Чтобы оставить комментарий, пожалуйста, войдите на сайт.
большая часть материалов из этой страницы даже не моё и не благодаря мне, а благодаря NightSiren'у и Hate'у, которых добавил в благодарности, это они всё придумали, даже видео хейта без его разрешения взял, найтсирен мне не раз помогал подобными функциями и формулами
и ты не представляешь как мне будет стыдно если кто-то посмотрит на это и подумает "оо, dfgdfhg такие прикольные штуки делает крута", мысль об этом заставляет застрелиться
Отредактирован Maxlaid
Пример использования: call RocketStrike(caster, x, y, "Abilities\\Weapons\\BansheeMissile\\BansheeMissile.mdl", ammout, dmg, 50., 200., DAMAGE_TYPE_FIRE)
Отредактирован ScorpioT1000