Как сделать, чтобы дальнобойные атаки юнитов не били сквозь препятствия?
Принятый ответ
код
не весь
globals
constant group TempG = CreateGroup( )
constant timer TempTimer = CreateTimer( )
constant real timerPeriodic = 0.01
boolean AbilityDamage = false
integer max = 0
unit array dummy
unit array target
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
real array damage
constant 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 IsEven takes integer a returns boolean
return a / 2 * 2 == a
endfunction
function move takes nothing returns nothing
local real x
local real y
local real z
local integer i
set i = 1
loop
set endx[i] = GetUnitX( target[i] )
set endy[i] = GetUnitY( target[i] )
set endz[i] = GetLocZ( endx[i], endy[i] ) + 50.00
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 SetUnitFacing( dummy[i], Atan2( y - GetUnitY( dummy[i] ), x - GetUnitX( dummy[i] ) ) * bj_RADTODEG )
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 or GetUnitFlyHeight( dummy[i] ) < 30.00 then
if time[i] >= 1.00 then
set AbilityDamage = true
call UnitDamageTarget( dummy[i], target[i], damage[i], false, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, null )
set AbilityDamage = false
endif
call KillUnit( dummy[i] )
if i != max then
set dummy[i] = dummy[max]
set target[i] = target[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 damage[i] = damage[max]
endif
set dummy[max] = null
set target[max] = null
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 DamageEvent_Actions takes nothing returns boolean
local unit attacker
local unit damaged
local real dmg = GetEventDamage( )
local real x
local real y
local real angle
local real angleOffset
local real distance
local real distanceOffset
local real height
local integer i
if not AbilityDamage and dmg > 0.00 then
set attacker = GetEventDamageSource( )
set damaged = GetTriggerUnit( )
set x = GetUnitX( damaged )
set y = GetUnitY( damaged )
call NegateDamage( damaged, dmg )
set dmg = dmg / 2.00
set height = 50.00
set angleOffset = 5
set distanceOffset = 0.00
set i = 0
loop
set max = max + 1
set startx[max] = GetUnitX( attacker )
set starty[max] = GetUnitY( attacker )
set startz[max] = GetLocZ( startx[max], starty[max] ) + height
set endx[max] = x
set endy[max] = y
set endz[max] = GetLocZ( endx[max], endy[max] ) + 50.00
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 target[max] = damaged
set dummy[max] = CreateUnit( GetOwningPlayer( attacker ), 'u000', startx[max], starty[max], angle * bj_RADTODEG )
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 distance = distance + distanceOffset
if IsEven( i ) then
set midx[max] = startx[max] + ( distance / 2.00 ) * Cos( angle + angleOffset * bj_DEGTORAD )
set midy[max] = starty[max] + ( distance / 2.00 ) * Sin( angle + angleOffset * bj_DEGTORAD )
else
set midx[max] = startx[max] + ( distance / 2.00 ) * Cos( angle - angleOffset * bj_DEGTORAD )
set midy[max] = starty[max] + ( distance / 2.00 ) * Sin( angle - angleOffset * bj_DEGTORAD )
endif
set midz[max] = 0.00
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] + height
if not IsEven( i ) then
set distanceOffset = distanceOffset + 50.00
set angleOffset = angleOffset + 180.00 / 16.00
set height = height + 20.00
endif
set time[max] = 0.00
set maxTime[max] = distance * 0.25 * timerPeriodic
set damage[max] = dmg
if max == 1 then
call TimerStart( TempTimer, timerPeriodic, true, function move )
endif
set i = i + 1
exitwhen i > 15
endloop
set damaged = null
set attacker = null
endif
return false
endfunction
//===========================================================================
function Regist takes unit u returns nothing
if GetUnitAbilityLevel( u, 'Aloc' ) == 0 then
call TriggerRegisterUnitEvent( gg_trg_DamageEvent, u, EVENT_UNIT_DAMAGED )
endif
endfunction
function RegistCond takes nothing returns boolean
call Regist( GetTriggerUnit( ) )
return false
endfunction
function RegistCond_1 takes nothing returns boolean
call Regist( GetFilterUnit( ) )
return false
endfunction
function RegistEvent takes nothing returns nothing
if gg_trg_DamageEvent != null then
call DestroyTrigger( gg_trg_DamageEvent )
endif
set gg_trg_DamageEvent = CreateTrigger( )
call GroupEnumUnitsInRect( TempG, bj_mapInitialPlayableArea, Condition( function RegistCond_1 ) )
call TriggerAddCondition( gg_trg_DamageEvent, Condition( function DamageEvent_Actions ) )
call TimerStart( GetExpiredTimer( ), 600.00, false, function RegistEvent )
endfunction
function InitTrig_DamageEvent takes nothing returns nothing
local trigger t = CreateTrigger( )
local region rectRegion = CreateRegion( )
call RegionAddRect( rectRegion, bj_mapInitialPlayableArea )
call TriggerRegisterEnterRegion( t, rectRegion, null )
call TriggerAddCondition( t, Condition( function RegistCond ) )
call TimerStart( CreateTimer( ), 0.00, false, function RegistEvent )
set t = null
set rectRegion = null
endfunction
Загруженные файлы
`
ОЖИДАНИЕ РЕКЛАМЫ...
Чтобы оставить комментарий, пожалуйста, войдите на сайт.
Отредактирован MpW
или нужен блок? можно сделать триггерно движение снарядов, когда снаряд врезается об щит ментально, делаем отскок, удаляем. если это атака, то проще сделать триггерно атаку, у одного мастера можно узнать. xgm.guru/user/rsfghd если если эта какая то способность, то мб проще сделать триггерно абилку снарядов.
большие минусы (которые лично мне никогда не были минусами), это то, что весь урон нужно делать триггерным, т.е. яды, скиллы из ро и прочая ерунда у юнита с такой атакой будут вызывать кастомные снаряды, тут поможет мемхак либо damage engine