XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > Warcraft> Академия: форум для вопросов> Jass
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

Ответ
 
Nerevar
I'll be back!
offline
Опыт: 18,352
Активность:
Код,вызывающий зависание
function Trig_stone_crush_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A00X'
endfunction

function stonecrush_m takes nothing returns nothing
local timer t=GetExpiredTimer()
local integer id=GetHandleId(t)
local integer level=LoadInteger(udg_ah,id,3)
local real angle=LoadReal(udg_ah,id,2)
local real distance=LoadReal(udg_ah,id,1)
local unit stone=LoadUnitHandle(udg_ah,id,0)
local real x=GetUnitX(stone)
local real y=GetUnitY(stone)
local unit dammi
local unit f
local group g=CreateGroup()
call GroupEnumUnitsInRange(g, x, y, 100, null)
loop
    set f = FirstOfGroup(g)
    exitwhen f == null
if IsPlayerEnemy(GetOwningPlayer(stone), GetOwningPlayer(f)) and (GetWidgetLife(f) > 0.405) and IsUnitType(f, UNIT_TYPE_STRUCTURE) != true and IsUnitType(f, UNIT_TYPE_MECHANICAL) != true and IsUnitType(f, UNIT_TYPE_ANCIENT) != true and IsUnitType(f, UNIT_TYPE_MAGIC_IMMUNE) != true then
else
    call GroupRemoveUnit(g, f)
endif
endloop
if distance<=10 or IsTerrainPathable(x+20*Cos(angle),y+20*Sin(angle),PATHING_TYPE_FLYABILITY) == true or IsUnitGroupEmptyBJ(g) == false then
    set f = FirstOfGroup(g)
    set dammi=CreateUnit(GetOwningPlayer(stone), 'u00A', x, y, 0)
    call UnitApplyTimedLife( dammi , 'BTLF',3 )
    call UnitAddAbility( dammi,'A02Z'  )
    call SetUnitAbilityLevel( dammi,'A02Z',  level )
    call IssueTargetOrder( dammi, "thunderbolt", f )
    call GroupClear(g)
    call DestroyGroup(g)
    call FlushChildHashtable(udg_ah,id)
    call PauseTimer(t)
    call DestroyTimer(t)
    call KillUnit(stone)
else
    call SetUnitZ(stone,GetRandomReal(60.,80.))
    call SetUnitPosition(stone,x+20*Cos(angle),y+20*Sin(angle))
endif
    set distance=distance-20
    call SaveReal(udg_ah,id,1,distance)
set t=null
set stone=null
set dammi=null
set f=null
call DestroyGroup(g)
set g=null
endfunction

function Trig_stone_crush_Actions takes nothing returns nothing
local unit caster=GetSpellAbilityUnit()
local real x=GetUnitX(caster)
local real y=GetUnitY(caster)
local real tx=GetSpellTargetX()
local real ty=GetSpellTargetY()
local real utx
local real uty
local timer t
local integer id
local group gn=CreateGroup()
local unit f
local integer level=GetUnitAbilityLevel(caster,'A00X' )
local unit stone
local real distance
local real angle
local real rangle
local real rdistance
    call GroupEnumUnitsInRange(gn, x, y, 450, null)
loop
    set f = FirstOfGroup(gn)
    exitwhen f == null
if IsUnitDeadBJ(f) == true then
    set x=GetUnitX(f)
    set y=GetUnitY(f)
    set stone=CreateUnit(GetOwningPlayer(caster), 'u00I', x, y, GetRandomReal(0.,360.))
    set rangle=GetRandomReal(0.,360.)
    set rdistance=GetRandomReal(0.,125.)
    set utx=tx+rdistance*CosBJ(rangle)
    set uty=ty+rdistance*SinBJ(rangle)
    set distance=SquareRoot((utx - x) * (utx - x) + (uty - y) * (uty - y))
    set angle=Atan2(uty-y,utx-x)
    set t=CreateTimer()
    set id=GetHandleId(t)
    call SaveUnitHandle(udg_ah,id,0,stone)
    call SaveReal(udg_ah,id,1,distance)
    call SaveReal(udg_ah,id,2,angle)
    call SaveInteger(udg_ah,id,3,level)
    call TimerStart(t,0.03,true,function stonecrush_m)
    call RemoveUnit(f)
endif
    call GroupRemoveUnit(gn, f)
endloop
set caster=null
set stone=null
set t=null
call DestroyGroup(gn)
set gn=null
set f=null
endfunction

//===========================================================================
function InitTrig_stone_crush takes nothing returns nothing
    set gg_trg_stone_crush = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_stone_crush, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_stone_crush, Condition( function Trig_stone_crush_Conditions ) )
    call TriggerAddAction( gg_trg_stone_crush, function Trig_stone_crush_Actions )
endfunction
-Для начала опишу,что он должен делать - при использовании магии вокруг героя создаются определенные юниты на позиции ближайших трупов(трупы при этом удаляются),затем летят в случайную точку рядом с целью каста,при этом,если они на пути врежутся в юнита,то оглушат его и нанесут урон.
-Сама проблема заключается в следующем - юниты создаются,трупы удаляются,юниты летят в нужные точки,только в том месте,где они должны врезаться в юнита на своем пути начинаются жестокие лаги,вызывающие зависание вара(причём если они ни во что не врежутся,то пролетят спокойно всё расстояние).
-Вопрос - чем может быть вызваны лаги?(также приветствуются предложения по оптимизации данного кода и оповещение о наличии утечек).
Старый 10.07.2011, 18:07
Doc

offline
Опыт: 63,163
Активность:
call GroupEnumUnitsInRange(g, x, y, 100, null)
loop
    set f = FirstOfGroup(g)
    exitwhen f == null
if IsPlayerEnemy(GetOwningPlayer(stone), GetOwningPlayer(f)) and (GetWidgetLife(f) > 0.405) and IsUnitType(f, UNIT_TYPE_STRUCTURE) != true and IsUnitType(f, UNIT_TYPE_MECHANICAL) != true and IsUnitType(f, UNIT_TYPE_ANCIENT) != true and IsUnitType(f, UNIT_TYPE_MAGIC_IMMUNE) != true then
else
    call GroupRemoveUnit(g, f)
endif
endloop
this.
Старый 10.07.2011, 18:33
Nerevar
I'll be back!
offline
Опыт: 18,352
Активность:
loop
    set f = FirstOfGroup(g)
    exitwhen f == null
if IsPlayerEnemy(GetOwningPlayer(stone), GetOwningPlayer(f))==false and (GetWidgetLife(f) < 0.405) or IsUnitType(f, UNIT_TYPE_STRUCTURE) == true or IsUnitType(f, UNIT_TYPE_MECHANICAL) == true or IsUnitType(f, UNIT_TYPE_ANCIENT) == true or IsUnitType(f, UNIT_TYPE_MAGIC_IMMUNE) == true then
call GroupRemoveUnit(g, f)
endif
endloop
Замена на это никак не помогла
Старый 10.07.2011, 18:49
Doc

offline
Опыт: 63,163
Активность:
Nerevar, интересно почему ... Попробуй подумать головой и перебрать ситуации, в которых цикл становится бесконечным. Я так вообще не понял зачем он.
Старый 10.07.2011, 19:03
Nerevar
I'll be back!
offline
Опыт: 18,352
Активность:
Ну этот цикл должен в созданной по координатам юнита группе отсеить всех ненужных,чтобы далее если она не пуста то остановить таймер,застанить и т.д.Я понял из-за чего происходит зацикливание...Вот я переделел под 2 групы(при отсеивании из 1 группы(если юнит подходящая цель) - добавляю во 2 группу,и уже её проверяю на наличие юнитов.
local group gn=CreateGroup()
local unit f
local group g=CreateGroup()
call GroupEnumUnitsInRange(g, x, y, 100, null)
loop
    set f = FirstOfGroup(g)
    exitwhen f == null
if IsPlayerEnemy(GetOwningPlayer(stone), GetOwningPlayer(f))==false or (GetWidgetLife(f) < 0.405) or IsUnitType(f, UNIT_TYPE_STRUCTURE) == true or IsUnitType(f, UNIT_TYPE_MECHANICAL) == true or IsUnitType(f, UNIT_TYPE_ANCIENT) == true or IsUnitType(f, UNIT_TYPE_MAGIC_IMMUNE) == true then
call GroupRemoveUnit(g, f)
else
call GroupRemoveUnit(g, f)
call GroupAddUnit(gn,f)
endif
endloop
if distance<=10 or IsTerrainPathable(x+20*Cos(angle),y+20*Sin(angle),PATHING_TYPE_FLYABILITY) == true or IsUnitGroupEmptyBJ(gn) == false then
    set f = FirstOfGroup(gn)
Старый 10.07.2011, 19:20
Helpmeplz

offline
Опыт: 11,738
Активность:
зачем вам лишняя группа
Код:
local integer i = 0
local group g = CreateGroup()
local unit f = null
//......
loop
    set f = FirstOfGroup(g)
    exitwhen f == null or CountUnitsInGroup(g) == i
if IsPlayerEnemy(GetOwningPlayer(stone), GetOwningPlayer(f)) and (GetWidgetLife(f) > 0.405) and not IsUnitType(f, UNIT_TYPE_STRUCTURE) and not IsUnitType(f, UNIT_TYPE_MECHANICAL) and not IsUnitType(f, UNIT_TYPE_ANCIENT) and not IsUnitType(f, UNIT_TYPE_MAGIC_IMMUNE) then
set i = i + 1
else
    call GroupRemoveUnit(g, f)
endif
endloop

и вместо != true используйте not

Отредактировано Helpmeplz, 10.07.2011 в 22:05.
Старый 10.07.2011, 19:46
DaSL

offline
Опыт: 276
Активность:
IsUnitDeadBJ(f) == true замени на IsUnitType(f, UNIT_TYPE_DEAD) == true
a остальное не смотрел
DaSL добавил:
IsUnitDeadBJ(f) == true замени на IsUnitType(f, UNIT_TYPE_DEAD) == true
a остальное не смотрел
Старый 11.07.2011, 00:41
Ответ

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы можете скачивать файлы

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 00:57.