Надумал я сделать у себя в карте триггерную способность, создающую стену - на подобии стены dark seer из Dota Allstars.
Собственно вопрос по реализации алгоритма поиска юнита, прошедшего через стену? Что лучше использовать, а так же с чем будет меньше гемороя в дальнейшем.
A) GroupPickUnitsInRange - пикаем всех в радиусе вокруг некой точки, основано на таймере и группе, дофига вычислений координат, туча действий с группами...
B) EventUnitsInRange - основано на одноименном событии триггера, создаем n даммиков в линию а после делаем данное событие на всех дамми, вроде просто но тут беда с условиями и еще хождение вдоль стены вызывает события, так же проблемность определения точки пересечения юнитом стены.
С) TriggerRegisterEnterRegion - основано тоже на триггере, ректе и куче регионов, собственно на которые вешается событие, с проверкой попроще, и проблемы с поиском примерной точки пересечения стены нету, но как то мутарно возится с целым массивом регинов...
Какой вариант решения задачи предложили вы?

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

Создаёт стену из магического льда, которая отталкивает противников от себя.
function IsUnitDeadBX takes unit u returns boolean
return GetUnitTypeId(u) == 0 or IsUnitType(u, UNIT_TYPE_DEAD)
endfunction

function IsTarget takes unit u,unit d returns boolean
return not IsUnitType(u,UNIT_TYPE_ANCIENT) and not IsUnitDeadBX(u)  and not IsUnitType(u, UNIT_TYPE_STRUCTURE) and not IsUnitType(u, UNIT_TYPE_MAGIC_IMMUNE) and (IsUnitEnemy(u, GetOwningPlayer(d)) or GetOwningPlayer(u) == Player(15))
endfunction

function SQ takes real xa, real ya, real xb, real yb returns real
return SquareRoot((xa-xb)*(xa-xb)+(ya-yb)*(ya-yb))
endfunction

function SafeX takes real pxx returns real
local real lfr=GetRectMinX(bj_mapInitialPlayableArea)+50
if(pxx<lfr)then
return lfr
endif
set lfr=GetRectMaxX(bj_mapInitialPlayableArea)-50
if(pxx>lfr)then
return lfr
endif
return pxx
endfunction

function SafeY takes real pyy returns real
local real lfr=GetRectMinY(bj_mapInitialPlayableArea)+50
if(pyy<lfr)then
return lfr
endif
set lfr=GetRectMaxY(bj_mapInitialPlayableArea)-50
if(pyy>lfr)then
return lfr
endif
return pyy
endfunction

function UBU takes unit u, unit d, unit c , real w returns boolean
local real x = GetUnitX(u)
local real y = GetUnitY(u)
local real r1 = 57.295827*Atan2(y-GetUnitY(d),x-GetUnitX(d))
local real r2 = 57.295827*Atan2(y-GetUnitY(c),x-GetUnitX(c))
set r2 = r2 -180
if r1 < 0.00 then
set r1 = r1 + 360
endif
if r2 < 0.00 then
set r2 = r2 + 360
endif
if r1 - r2  <= w and r1 - r2  >= -(w) then
return true
else
return false
endif
endfunction


function IceWallCon takes nothing returns boolean
return GetSpellAbilityId() == 'A0KP'
endfunction

function IceWallCreate takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetHandleId(t)
local unit c = LoadUnitHandle(udg_AssassinHash,id,0)
local real r = LoadReal(udg_AssassinHash,id,3)
local integer i = LoadInteger(udg_AssassinHash,id,4)
local integer j = LoadInteger(udg_AssassinHash,id,5)
local real x = LoadReal(udg_AssassinHash,id,StringHash("X"))
local real y = LoadReal(udg_AssassinHash,id,StringHash("Y"))
local real a = 0.
local real b = 0.
local boolean e = LoadBoolean(udg_AssassinHash,id,6)
local boolean f = LoadBoolean(udg_AssassinHash,id,7)
local boolean k = LoadBoolean(udg_AssassinHash,id,8)
local integer n = LoadInteger(udg_AssassinHash,id,25)
local real X2 = LoadReal(udg_AssassinHash,id,StringHash("X2"))
local real Y2 = LoadReal(udg_AssassinHash,id,StringHash("Y2"))
local real X3 = LoadReal(udg_AssassinHash,id,StringHash("X3"))
local real Y3 = LoadReal(udg_AssassinHash,id,StringHash("Y3"))
local integer h = 0
local group g = LoadGroupHandle(udg_AssassinHash,id,2)
local unit u
local unit d
local unit d1
if e == false then
set i = i+1
set j = j+1
if i < 7 then
set a = SafeX(x+(80.*i)*Cos(r))
set b = SafeY(y+(80.*i)*Sin(r))
set d = CreateUnit(GetOwningPlayer(c),'e00V',a,b,0)
call UnitAddAbility(d,'Arav')
call UnitRemoveAbility(d,'Arav')
call SetUnitFlyHeight(d,150,0)
call DestroyEffect(AddSpecialEffect("FrozenOrbBall.mdx",a,b))
call DestroyEffect(AddSpecialEffect("Abilities\\Weapons\\SpiritOfVengeanceMissile\\SpiritOfVengeanceMissile.mdl",a,b))
call SaveUnitHandle(udg_AssassinHash,id,StringHash("IWU1"+I2S(i)),d)
set a = SafeX(x-(80.*j)*Cos(r))
set b = SafeY(y-(80.*j)*Sin(r))
set d = CreateUnit(GetOwningPlayer(c),'e00V',a,b,0)
call UnitAddAbility(d,'Arav')
call UnitRemoveAbility(d,'Arav')
call SetUnitFlyHeight(d,150,0)
call DestroyEffect(AddSpecialEffect("FrozenOrbBall.mdx",a,b))
call DestroyEffect(AddSpecialEffect("Abilities\\Weapons\\SpiritOfVengeanceMissile\\SpiritOfVengeanceMissile.mdl",a,b))
call SaveUnitHandle(udg_AssassinHash,id,StringHash("IWU2"+I2S(j)),d)
call SaveInteger(udg_AssassinHash,id,4,i)
call SaveInteger(udg_AssassinHash,id,5,j)
else
call SaveBoolean(udg_AssassinHash,id,6,true)
endif
else
if f == false then
call SaveInteger(udg_AssassinHash,id,4,0)
call SaveReal(udg_AssassinHash,id,3,r-1.566)
call TimerStart(t,.025,true,function IceWallCreate)
call SaveBoolean(udg_AssassinHash,id,7,true)
else
set i = i+1
if i < 201 then
call SaveInteger(udg_AssassinHash,id,4,i)
set d = LoadUnitHandle(udg_AssassinHash,id,StringHash("IWU16"))
set d1 = LoadUnitHandle(udg_AssassinHash,id,StringHash("IWU26"))
call GroupClear(udg_G)
call GroupEnumUnitsInRange(udg_G,x,y,1040,null)
loop
set u = FirstOfGroup(udg_G)
if IsTarget(u,c) and UBU(u,d,d1,20.) and IsUnitInGroup(u,g) == false then
call GroupAddUnit(g,u)
if GetUnitAbilityLevel(c,'B009') > 0 then
call UnitDamageTarget(c,u,150.+80.*GetUnitAbilityLevel(c,'A0KP'),true,true,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_MAGIC,null)
else
call UnitDamageTarget(c,u,75.+40.*GetUnitAbilityLevel(c,'A0KP'),true,true,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_MAGIC,null)
endif
set n = n+1
call SaveInteger(udg_AssassinHash,id,25,n)
call SaveInteger(udg_AssassinHash,id,StringHash("IWI"+I2S(n)),15)
if SQ(X3,Y3,GetUnitX(u),GetUnitY(u)) > SQ(X2,Y2,GetUnitX(u),GetUnitY(u)) then
call SaveReal(udg_AssassinHash,id,StringHash("IWR"+I2S(n)),LoadReal(udg_AssassinHash,id,20))
else
call SaveReal(udg_AssassinHash,id,StringHash("IWR"+I2S(n)),LoadReal(udg_AssassinHash,id,21))
endif
call SaveUnitHandle(udg_AssassinHash,id,StringHash("IWU"+I2S(n)),u)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\FrostArrows\\NagaColdArrowMissile.mdl",u,"chest"))
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Weapons\\SpiritOfVengeanceMissile\\SpiritOfVengeanceMissile.mdl",u,"chest"))
endif
call GroupRemoveUnit(udg_G,u)
exitwhen u == null
endloop
set i = 1
if n > 0 then
loop
exitwhen i > n
set h = LoadInteger(udg_AssassinHash,id,StringHash("IWI"+I2S(i)))-1
set r = LoadReal(udg_AssassinHash,id,StringHash("IWR"+I2S(i)))
set u = LoadUnitHandle(udg_AssassinHash,id,StringHash("IWU"+I2S(i)))
call SaveInteger(udg_AssassinHash,id,StringHash("IWI"+I2S(i)),h)
call SetUnitPathing(u,false)
call SetUnitX(u,SafeX(GetUnitX(u)+15.*Cos(r)))
call SetUnitY(u,SafeY(GetUnitY(u)+15.*Sin(r)))
call IssueImmediateOrder(u,"stop")
if ModuloInteger(h,3) == 0 then
call DestroyEffect(AddSpecialEffectTarget("FrozenOrbBall.mdx",u,"chest"))
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Weapons\\SpiritOfVengeanceMissile\\SpiritOfVengeanceMissile.mdl",u,"chest"))
endif
set i = i + 1
endloop
set i = 1
loop
exitwhen i > n
set h = LoadInteger(udg_AssassinHash,id,StringHash("IWI"+I2S(i)))
set u = LoadUnitHandle(udg_AssassinHash,id,StringHash("IWU"+I2S(i)))
if h <= 0 or IsUnitDeadBX(u) or not IsTarget(u,c) then
set j = i
call GroupRemoveUnit(g,u)
call SetUnitPathing(u,true)
loop
exitwhen j > n
call SaveReal(udg_AssassinHash,id,StringHash("IWR"+I2S(j)),LoadReal(udg_AssassinHash,id,StringHash("IWR"+I2S(j+1))))
call SaveInteger(udg_AssassinHash,id,StringHash("IWI"+I2S(j)),LoadInteger(udg_AssassinHash,id,StringHash("IWI"+I2S(j+1))))
call SaveUnitHandle(udg_AssassinHash,id,StringHash("IWU"+I2S(j)),LoadUnitHandle(udg_AssassinHash,id,StringHash("IWU"+I2S(j+1))))
set j = j + 1
endloop
set n = n-1
call SaveInteger(udg_AssassinHash,id,25,n)
endif
set i = i + 1
endloop
endif
else
set i = 1
if n > 0 then
loop
exitwhen i > n
set h = LoadInteger(udg_AssassinHash,id,StringHash("IWI"+I2S(i)))-1
set r = LoadReal(udg_AssassinHash,id,StringHash("IWR"+I2S(i)))
set u = LoadUnitHandle(udg_AssassinHash,id,StringHash("IWU"+I2S(i)))
call SaveInteger(udg_AssassinHash,id,StringHash("IWI"+I2S(i)),h)
call SetUnitPathing(u,false)
call SetUnitX(u,SafeX(GetUnitX(u)+15.*Cos(r)))
call SetUnitY(u,SafeY(GetUnitY(u)+15.*Sin(r)))
call IssueImmediateOrder(u,"stop")
if ModuloInteger(h,3) == 0 then
call DestroyEffect(AddSpecialEffectTarget("FrozenOrbBall.mdx",u,"chest"))
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Weapons\\SpiritOfVengeanceMissile\\SpiritOfVengeanceMissile.mdl",u,"chest"))
endif
set i = i + 1
endloop
set i = 1
loop
exitwhen i > n
set h = LoadInteger(udg_AssassinHash,id,StringHash("IWI"+I2S(i)))
set u = LoadUnitHandle(udg_AssassinHash,id,StringHash("IWU"+I2S(i)))
if h <= 0 or IsUnitDeadBX(u) then
set j = i
call GroupRemoveUnit(g,u)
call SetUnitPathing(u,true)
loop
exitwhen j > n
call SaveReal(udg_AssassinHash,id,StringHash("IWR"+I2S(j)),LoadReal(udg_AssassinHash,id,StringHash("IWR"+I2S(j+1))))
call SaveInteger(udg_AssassinHash,id,StringHash("IWI"+I2S(j)),LoadInteger(udg_AssassinHash,id,StringHash("IWI"+I2S(j+1))))
call SaveUnitHandle(udg_AssassinHash,id,StringHash("IWU"+I2S(j)),LoadUnitHandle(udg_AssassinHash,id,StringHash("IWU"+I2S(j+1))))
set j = j + 1
endloop
set n = n-1
call SaveInteger(udg_AssassinHash,id,25,n)
endif
set i = i + 1
endloop
endif
if k == false then
set j = 1
loop
exitwhen j > 6
set d = LoadUnitHandle(udg_AssassinHash,id,StringHash("IWU1"+I2S(j)))
call DestroyEffect(AddSpecialEffect("FrozenOrbBall.mdx",GetUnitX(d),GetUnitY(d)))
call DestroyEffect(AddSpecialEffect("Abilities\\Weapons\\SpiritOfVengeanceMissile\\SpiritOfVengeanceMissile.mdl",GetUnitX(d),GetUnitY(d)))
call KillUnit(d)
set j = j + 1
endloop
set j = 1
loop
exitwhen j > 6
set d = LoadUnitHandle(udg_AssassinHash,id,StringHash("IWU2"+I2S(j)))
call DestroyEffect(AddSpecialEffect("FrozenOrbBall.mdx",GetUnitX(d),GetUnitY(d)))
call DestroyEffect(AddSpecialEffect("Abilities\\Weapons\\SpiritOfVengeanceMissile\\SpiritOfVengeanceMissile.mdl",GetUnitX(d),GetUnitY(d)))
call KillUnit(d)
set j = j + 1
endloop
set d = LoadUnitHandle(udg_AssassinHash,id,StringHash("IWU"))
call KillUnit(d)
call DestroyEffect(AddSpecialEffect("FrozenOrbBall.mdx",GetUnitX(d),GetUnitY(d)))
call DestroyEffect(AddSpecialEffect("Abilities\\Weapons\\SpiritOfVengeanceMissile\\SpiritOfVengeanceMissile.mdl",GetUnitX(d),GetUnitY(d)))
call SaveBoolean(udg_AssassinHash,id,8,true)
endif
if k and n <= 0 then
call DestroyGroup(g)
call DestroyTimer(t)
call FlushChildHashtable(udg_AssassinHash,id)
endif
endif
endif
endif
set t = null
set c = null
set d = null
set d1 = null
set g = null
set u = null
endfunction

function IceWall takes nothing returns nothing
local unit c =  GetSpellAbilityUnit()
local real a = GetUnitX(c)
local real b = GetUnitY(c)
local real x = SafeX(GetSpellTargetX())
local real y = SafeY(GetSpellTargetY())
local real r = Atan2(y-b,x-a)+1.566
local timer t = CreateTimer()
local real dist = SQ(a,b,x,y)*2.
local integer id = GetHandleId(t)
local unit d
set d = CreateUnit(GetOwningPlayer(c),'e00V',x,y,0)
call UnitAddAbility(d,'Arav')
call UnitRemoveAbility(d,'Arav')
call SetUnitFlyHeight(d,150,0)
call SaveUnitHandle(udg_AssassinHash,id,StringHash("IWU"),d)
call DestroyEffect(AddSpecialEffect("FrozenOrbBall.mdx",x,y))
call DestroyEffect(AddSpecialEffect("Abilities\\Weapons\\SpiritOfVengeanceMissile\\SpiritOfVengeanceMissile.mdl",x,y))
call SaveUnitHandle(udg_AssassinHash,id,0,c)
call SaveReal(udg_AssassinHash,id,3,r)
set r = Atan2(y-b,x-a)
call SaveReal(udg_AssassinHash,id,20,r)
call SaveReal(udg_AssassinHash,id,21,Atan2(b-y,a-x))
call SaveReal(udg_AssassinHash,id,StringHash("X2"),a+dist*Cos(r))
call SaveReal(udg_AssassinHash,id,StringHash("Y2"),b+dist*Sin(r))
call SaveReal(udg_AssassinHash,id,StringHash("X3"),a)
call SaveReal(udg_AssassinHash,id,StringHash("Y3"),b)
call SaveGroupHandle(udg_AssassinHash,id,2,CreateGroup())
call SaveReal(udg_AssassinHash,id,StringHash("X"),x)
call SaveReal(udg_AssassinHash,id,StringHash("Y"),y)
call TimerStart(t,.025,true,function IceWallCreate)
set t = null
set c = null
set d = null
endfunction
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
0
32
8 лет назад
0
nvc123:
quq_CCCP, в (( код jass пробел убери
А спс, не проверил.
Ну народ, предложит че нить дельное?
0
28
8 лет назад
0
quq_CCCP, я бы пикал в неком ректе (где твоя стена является диагональю)
а потом через координаты проверял прошёл ли юнит через стену или нет
0
32
8 лет назад
0
nvc123:
quq_CCCP, я бы пикал в неком ректе (где твоя стена является диагональю)
а потом через координаты проверял прошёл ли юнит через стену или нет
Тут понадобится 1200 \ 32 регионов, вошел в регион из массива, тут же надо записывать в группу и проверять что юнит вышел и региона не войдя в другой...
Так же я пока не придумал как реализовать защиту от того что юнит залез сразу в 2 региона или 3...
Я вот и решил послушать, то что то у меня голова кругом от казалось бы пустяковой скиллки...
0
17
8 лет назад
0
quq_CCCP, я могу предложить способ с использованием даммиков. Каждому даммику даешь ауру с радиусом действия 100-150 ( ну в зависимости от размера стены). При прохождении через стенку будет вешаться эффект ауры. Поиск нужных тебе юнитов по наложенному эффекту от ауры.
0
32
8 лет назад
0
KPOKODIL:
quq_CCCP, я могу предложить способ с использованием даммиков. Каждому даммику даешь ауру с радиусом действия 100-150 ( ну в зависимости от размера стены). При прохождении через стенку будет вешаться эффект ауры. Поиск нужных тебе юнитов по наложенному эффекту от ауры.
Все бы хорошо, но обновление баффа не отследить, длительность баффа ауры тоже, там рандом по времени действия...
Еще боюсь если кто то быстро пролетит через стену не получит бафф ауры...
0
17
8 лет назад
0
quq_CCCP, а можно поинтересоваться, что будет делать твоя стенка? Только иллюзии?
0
28
8 лет назад
Отредактирован nvc123
0
Тут понадобится 1200 \ 32 регионов
1 стена-1 большой регион
всё остальное через координаты и атач структуры к юниту
0
20
8 лет назад
Отредактирован ssbbssc
0
а нельзя создать 5 (допустим) регионов меньше и затем передвигать их в нужном порядке, выстраивая из них необходимую область?
то есть если знаем координаты, берем точку каста - проводим перпендикуляр от кастера - и выстраиваем наши регионы вдоль линии нужной тебе длинны
0
28
8 лет назад
0
ssbbssc, это и есть вариант C
0
20
8 лет назад
0
nvc123:
ssbbssc, это и есть вариант C
сорян =\
0
32
8 лет назад
0
KPOKODIL:
quq_CCCP, а можно поинтересоваться, что будет делать твоя стенка? Только иллюзии?
Небудет иллюзий, вообще небудет, совсем небудет!!!!
Так если для справки Юнита бьет молния из стены и замедляет нанося единожды урон и сжигая ману, чем Юнит дальше отошел от стены тем слабее замедление...
Короче у меня тут ступор - а как же все это реализовать, каким путем пойти?
nvc123:
Тут понадобится 1200 \ 32 регионов
1 стена-1 большой регион
всё остальное через координаты и атач структуры к юниту
Про это прошу поподробнее, стена может быть под любым углом, от 0 до 360 и как мне регион 1 под углом запилить?
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.