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

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

Закрытая тема
 
freest

offline
Опыт: 442
Активность:
Утечка в коде, или неправильный код.
В общем: сделал скилл как у Windrunner стрела в доте, летит создает спецэффект по за собой, на пути наносит урон, рубит деревья, в конце полета уничтожается и происходит взрыв в области, создаются дамми и стунит юнитов.
Когда использует первый игрок все нормально, но после 40-50 применений начинает лагать.
Когда использует другой игрок, создается спецэффект взрыва в центре карты с периодичностью в ~0,4 секунды, неважно куда летела стрела.
Собстна код:
((код jass
globals
unit u
endglobals
function arrow_cond takes nothing returns boolean
return GetSpellAbilityId() == 'A00B'
endfunction
function FilterUnit takes nothing returns boolean
return IsPlayerEnemy(GetOwningPlayer(u) ,GetOwningPlayer(GetFilterUnit())) and GetWidgetLife(GetFilterUnit())>=0.405 and not IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE) and not IsUnitType(GetFilterUnit(),UNIT_TYPE_MAGIC_IMMUNE)and not IsUnitType(GetFilterUnit(),UNIT_TYPE_FLYING)
endfunction
function arrow_damage takes nothing returns nothing
local integer lvl = GetUnitAbilityLevel(u, 'A00B')
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIfb\\AIfbSpecialArt.mdl",​ GetEnumUnit(), "overhead"))
call UnitDamageTargetBJ( u, GetEnumUnit(), (10*I2R(lvl)), ATTACK_TYPE_MAGIC, DAMAGE_TYPE_FIRE )
call KillDestructable(GetEnumDestructable())
endfunction
function arrow_explosion takes nothing returns nothing
local integer lvl = GetUnitAbilityLevel(u, 'A00B')
local unit d = CreateUnit(GetOwningPlayer(u), 'h001', GetUnitX(GetEnumUnit()), GetUnitY(GetEnumUnit()), 0)
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\Incinerate\\FireLordDeathExplod​e.mdl", GetEnumUnit(), "origin"))
call KillDestructable(GetEnumDestructable())
call UnitApplyTimedLife(d, 'BTLF', 1.5)
call ShowUnitHide(d)
call IssueTargetOrder(d, "thunderbolt", GetEnumUnit())
call UnitDamageTargetBJ( u, GetEnumUnit(), (100*I2R(lvl)), ATTACK_TYPE_MAGIC, DAMAGE_TYPE_FIRE )
set d = null
endfunction
function arrow_move takes nothing returns nothing
local integer i = GetHandleId(GetExpiredTimer())
local unit d = LoadUnitHandle(udg_h, i, 0)
local real a = LoadReal(udg_h, i, 1)
local real x2 = GetUnitX(d) + 40.00 * Cos(a*bj_DEGTORAD)
local real y2 = GetUnitY(d) + 40.00 * Sin(a*bj_DEGTORAD)
local real x = LoadReal(udg_h, i, 2)
local real y = LoadReal(udg_h, i, 3)
local real dist = SquareRoot((x2-x)*(x2-x)+(y2-y)*(y2-y))
local group g = CreateGroup()
local group ge = CreateGroup()
local effect e
if d != null then
call DestroyEffect(AddSpecialEffect("Environment\\NightElfBuildingFire\\ElfLargeBuildingFire2.mdl&qu​ot;, x2, y2))
endif
set u = LoadUnitHandle(udg_h, i, 4)
call GroupEnumUnitsInRange(g, GetUnitX(d), GetUnitY(d), 150, Condition(function FilterUnit))
call ForGroup(g, function arrow_damage)
call EnumDestructablesInCircleBJ(150, Location(x2,y2),(function arrow_damage))
if dist < 1800 then
call SetUnitPosition(d, x2, y2)
else
call GroupEnumUnitsInRange(ge, GetUnitX(d), GetUnitY(d), 300, Condition(function FilterUnit))
call EnumDestructablesInCircleBJ(300, Location(x2,y2),(function arrow_explosion))
call ForGroup(ge, function arrow_explosion)
set e = AddSpecialEffect("Objects\\Spawnmodels\\Other\\NeutralBuildingExplosion\\NeutralBuildingExplosi​on.mdl", GetUnitX(d), GetUnitY(d))
call RemoveUnit(d)
call DestroyEffect(e)
endif
call DestroyGroup(g)
call DestroyGroup(ge)
set e = null
set g = null
set ge = null
set d = null
endfunction
function arrow_act takes nothing returns nothing
local timer t = CreateTimer()
local integer i = GetHandleId(t)
local unit c = GetSpellAbilityUnit()
local real cx = GetUnitX(c)
local real cy = GetUnitY(c)
local real tx = GetSpellTargetX()
local real ty = GetSpellTargetY()
call SaveUnitHandle(udg_h, i, 0, CreateUnit(GetOwningPlayer(c), 'h003',cx , cy, bj_RADTODEG*Atan2(ty-cy,tx-cx)))
call SaveReal(udg_h, i, 1, bj_RADTODEG*Atan2(ty-cy,tx-cx))
call SaveReal(udg_h, i, 2, GetUnitX(GetSpellAbilityUnit()))
call SaveReal(udg_h, i, 3, GetUnitY(GetSpellAbilityUnit()))
call SaveUnitHandle(udg_h, i, 4, c)
call TimerStart(t, 0.03125, true, function arrow_move)
call DestroyEffect(AddSpecialEffect("Environment\\NightElfBuildingFire\\ElfLargeBuildingFire2.mdl&qu​ot;, cx, cy))
set t = null
set c = null
endfunction
function InitTrig_Arrow takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_CAST)
call TriggerAddCondition(t, Condition(function arrow_cond))
call TriggerAddAction(t, function arrow_act)
endfunction
))

Отредактировано freest, 18.02.2012 в 18:45.
Старый 18.02.2012, 18:14
alpha

offline
Опыт: 7,387
Активность:
перенеси код нормально, тут спецсимволы какие-то, мусор всякий
оформи как код jass согласно форматированию, если автоопределение не срабатывает как надо
Старый 18.02.2012, 18:36
Doc

offline
Опыт: 63,163
Активность:
gimme map.
Старый 18.02.2012, 18:38
freest

offline
Опыт: 442
Активность:
alpha:
перенеси код нормально, тут спецсимволы какие-то, мусор всякий
оформи как код jass согласно форматированию, если автоопределение не срабатывает как надо
код и без того можно прочесть, спецсимволы вставлены всего в двух местах, в путях к спецэффектам.
Старый 19.02.2012, 09:16
Nerevar
I'll be back!
offline
Опыт: 18,352
Активность:
Судя по твоему коду,стрела будет наносить урон по каждому юниту не 2 раза(при полете 1 и при взрыве) а постоянно(при полете вокруг дпс и при взрыве) - так и оставлять или сделать чтобы 2 раза урон наносился?
Вот изменил код,чтобы наносило урон юниту 2 раза(при задевании и взрыве),также кое-что убрал,кое-что добавил,устранил утечки,должно работать^^
» Code
function arrow_cond takes nothing returns boolean
    return GetSpellAbilityId() == 'A00B' 
endfunction
 
function kill_destr takes nothing returns nothing
    call KillDestructable(GetEnumDestructable())
endfunction
  
function arrow_move takes nothing returns nothing
local timer t=GetExpiredTimer()
local integer id = GetHandleId(t)
local unit d = LoadUnitHandle(udg_h, id, 0)
local real a = LoadReal(udg_h, id, 1)
local real dist = LoadReal(udg_h, id, 2)
local unit caster = LoadUnitHandle(udg_h,id,3)
local group pg = LoadGroupHandle(udg_h,id,4)
local real x2 = GetUnitX(d) + 40. * Cos(a)
local real y2 = GetUnitY(d) + 40. * Sin(a)
local integer level=GetUnitAbilityLevel(caster, 'A00B')
local group g=CreateGroup()
local location loc=Location(x2,y2)
local unit f
local unit d2
if dist < 1800. then
    call DestroyEffect(AddSpecialEffect("Environment//NightElfBuildingFire//ElfLargeBuildingFire2.mdl&qu​ot;, x2, y2)) 
    call GroupEnumUnitsInRange(g, GetUnitX(d), GetUnitY(d), 150., null)
loop
    set f=FirstOfGroup(g)
    exitwhen f==null
if not IsUnitInGroup(f,pg) and IsPlayerEnemy(GetOwningPlayer(caster) ,GetOwningPlayer(f)) and GetWidgetLife(f)>=0.405 and not IsUnitType(f,UNIT_TYPE_STRUCTURE) and not IsUnitType(f,UNIT_TYPE_MAGIC_IMMUNE)and not IsUnitType(f,UNIT_TYPE_FLYING) then
    call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Items\\AIfb\\AIfbSpecialArt.mdl",​f, "overhead"))
    call UnitDamageTarget(caster, f, 10.*level, true, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_FIRE, WEAPON_TYPE_WHOKNOWS)
endif
    call GroupRemoveUnit(g,f)
    call GroupAddUnit(pg,f)
endloop
    call EnumDestructablesInCircleBJ(150., loc,(function kill_destr))
    call SetUnitX(d,x2)
    call SetUnitY(d,y2)
    call SaveReal(udg_h,id,2,dist-40.)
else
    call GroupEnumUnitsInRange(g, GetUnitX(d), GetUnitY(d), 300., null)
loop
    set f=FirstOfGroup(g)
    exitwhen f==null
if IsPlayerEnemy(GetOwningPlayer(caster) ,GetOwningPlayer(f)) and GetWidgetLife(f)>=0.405 and not IsUnitType(f,UNIT_TYPE_STRUCTURE) and not IsUnitType(f,UNIT_TYPE_MAGIC_IMMUNE)and not IsUnitType(f,UNIT_TYPE_FLYING) then
    set d2 = CreateUnit(GetOwningPlayer(caster), 'h001', x2, y2, 0.)
    call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\Incinerate\\FireLordDeathExplod​?&#8203;e.mdl",f, "origin"))
    call UnitApplyTimedLife(d2, 'BTLF', 0.5)
    call ShowUnit(d2,false)
    call IssueTargetOrder(d2, "thunderbolt", f) 
    call UnitDamageTarget(caster, f, 100.*level, true, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_FIRE, WEAPON_TYPE_WHOKNOWS)
endif
    call GroupRemoveUnit(g,f)
endloop    
    call EnumDestructablesInCircleBJ(300., loc,(function kill_destr))
    call DestroyEffect(AddSpecialEffect("Objects//Spawnmodels//Other//NeutralBuildingExplosion//NeutralB​uildingExplosion.mdl", GetUnitX(d), GetUnitY(d)))
    call KillUnit(d)
    call GroupClear(pg)
    call DestroyGroup(pg)
    call PauseTimer(t)
    call DestroyTimer(t)
    call FlushChildHashtable(udg_h,id)
endif
    call DestroyGroup(g)
    call RemoveLocation(loc)
set loc = null
set caster = null
set t = null
set g = null
set f = null
set pg = null
set d = null
set d2=null
endfunction
 
function arrow_act takes nothing returns nothing
local timer t = CreateTimer()
local integer id = GetHandleId(t)
local unit caster = GetTriggerUnit()
local real cx = GetUnitX(caster)
local real cy = GetUnitY(caster)
local real tx = GetSpellTargetX()
local real ty = GetSpellTargetY() 
     call SaveUnitHandle(udg_h, id, 0, CreateUnit(GetOwningPlayer(caster), 'h003',cx , cy, bj_RADTODEG*Atan2(ty-cy,tx-cx)))
     call SaveReal(udg_h, id, 1, Atan2(ty-cy,tx-cx))
     call SaveReal(udg_h, id, 2, SquareRoot((tx-cx)*(tx-cx)+(ty-cy)*(ty-cy)))
     call SaveUnitHandle(udg_h, id, 3, caster) 
     call SaveGroupHandle(udg_h,id,4,CreateGroup())
     call TimerStart(t, 0.03, true, function arrow_move)
     call DestroyEffect(AddSpecialEffect("Environment//NightElfBuildingFire//ElfLargeBuildingFire2.mdl&qu​ot;, cx, cy)) 
set t = null
set caster = null
endfunction
 
function InitTrig_Arrow takes nothing returns nothing
 set gg_trg_Arrow = CreateTrigger()
 call TriggerRegisterAnyUnitEventBJ(gg_trg_Arrow, EVENT_PLAYER_UNIT_SPELL_EFFECT)
 call TriggerAddCondition(gg_trg_Arrow, Condition(function arrow_cond))
 call TriggerAddAction(gg_trg_Arrow, function arrow_act)
endfunction

Отредактировано Nerevar, 19.02.2012 в 10:24.
Старый 19.02.2012, 10:08
FLESHNIK

offline
Опыт: 384
Активность:
Таймер не удалил.
Старый 19.02.2012, 11:25
MpW

offline
Опыт: 49,815
Активность:
freest,
еще группы можно было 1 раз создать, в начале действия, тут у тебя каждый раз создаются по-новому, потом удаляются, лучше так:
создал ее, запомнил в хэше, и потом через каждые n-секунды по таймеру ты ее используешь таким образом:
выделил всех юнитов в группу, скажем в группу g
Код:
GroupEnumUnitsInRange(g, GetUnitX(d), GetUnitY(d), 150., null)

потом сделал нужные действия через ForGroup или просто обычным циклом (скажем дамаг даммикаст итд)
затем эту можно просто очистить, а когда она не нужно уничтожать ее вместе с таймером

насчет EnumDestructablesInCircleBJ была у меня такая тема, где не хотел использовать локалку

[h3]Steal nerves добавил:
» вот код

Код:
function Trig_PowerShot_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A02L'
endfunction
function Trig_Powershot takes nothing returns nothing
local real xf = GetDestructableX(GetEnumDestructable())
local real yf = GetDestructableY(GetEnumDestructable())
local real x = xf-GetUnitX(udg_Unit)
local real y = yf-GetUnitY(udg_Unit)
if SquareRoot((x*x)+(y*y)) <= 150 then
call KillDestructable( GetEnumDestructable() )
endif
endfunction
function Trig_Powershot_CCC takes nothing returns nothing
local real damage = GetUnitStateSwap(UNIT_STATE_LIFE, GetEnumUnit())
local texttag tag = CreateTextTag()
call UnitDamageTarget( udg_Unit, GetEnumUnit(), udg_PowerShot_Damage, true, false, ATTACK_TYPE_MELEE, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
set udg_PowerShot_Damage = udg_PowerShot_Damage * 0.90
call DestroyEffect(AddSpecialEffectTarget( "Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl", GetEnumUnit(),"chest" ))
set damage = damage - GetUnitStateSwap(UNIT_STATE_LIFE, GetEnumUnit())
call SetTextTagPermanent( tag, false )
call SetTextTagText(tag, I2S(R2I(damage)), TextTagSize2Height(10))
call SetTextTagPosUnit(tag, GetEnumUnit(), 50.00)
call SetTextTagColor(tag, PercentTo255(15.00), PercentTo255(15.00), PercentTo255(100.00), PercentTo255(100.0-0))
call SetTextTagVelocity(tag, 0.00, 0.027)
call SetTextTagFadepoint( tag, 1.00 )
call SetTextTagLifespan( tag, 2.00 )
call GroupAddUnit( udg_Group, GetEnumUnit() )
set tag = null
endfunction
function Conditions_Powershot takes nothing returns boolean
return nounit(GetFilterUnit()) == true and (IsUnitInGroup(GetFilterUnit(), udg_Group) == false) and (IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(udg_Unit)) == true) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false) and (IsUnitAliveBJ(GetFilterUnit()) == true)
endfunction
function Effect_PowerShot takes nothing returns nothing
local timer try = GetExpiredTimer()
local effect e = LoadEffectHandle(udg_Hash, GetHandleId(try), 1)
call FlushChildHashtable(udg_Hash, GetHandleId(try))
call DestroyEffect( e )
call DestroyTimer(try)
set e = null
set try = null
endfunction
function Timer_PowerShot takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetHandleId(t)
local unit u1 = LoadUnitHandle(udg_Hash, id, 1)
local unit u2 = LoadUnitHandle(udg_Hash, id, 2)
local real angle = LoadReal(udg_Hash, id, 3)
local real dist = LoadReal(udg_Hash, id, 4)
local real d = LoadReal(udg_Hash, id, 5)
local real x = GetUnitX(u2)
local real y = GetUnitY(u2)
local timer try = null
local effect e = null
local group g = null
local rect re = LoadRectHandle(udg_Hash, id, 9)
if d < dist then //тут устанавливаем необходимую дистанцию которую пролетит стрела, у меня тут она летит от кастера до точки цели (то есть dist между ними не превышает)
set try = CreateTimer()
set e = AddSpecialEffect( "Abilities\\Spells\\Other\\Tornado\\Tornado_Target.mdl", x, y )
set g = LoadGroupHandle(udg_Hash, GetHandleId(t), 8)
set x = x + 50 * Cos(angle * bj_DEGTORAD)
set y = y + 50 * Sin(angle * bj_DEGTORAD)
set d = d + 50
call RemoveSavedReal(udg_Hash, id, 5)
call SaveReal(udg_Hash, id, 5, d)
call SetUnitX( u2, x)
call SetUnitY( u2, y)
call MoveRectTo(re, x, y)
call SaveEffectHandle(udg_Hash, GetHandleId(try), 1, e)
call TimerStart(try, 2.00, false, function Effect_PowerShot )
set udg_Unit = LoadUnitHandle(udg_Hash, id, 1)
set udg_Group = LoadGroupHandle(udg_Hash, id, 6)
set udg_PowerShot_Damage = LoadReal(udg_Hash, id, 7)
call GroupEnumUnitsInRange(g, x, y, 150, Condition(function Conditions_Powershot))
call ForGroup( g, function Trig_Powershot_CCC)
set udg_Unit = u2
call RemoveSavedReal(udg_Hash, id, 7)
call SaveReal(udg_Hash, id, 7, udg_PowerShot_Damage)
call EnumDestructablesInRect(re,null,function Trig_Powershot)
call GroupClear(g)
else
call PauseTimer(t)
call DestroyGroup(LoadGroupHandle(udg_Hash, id, 8))
call DestroyGroup(LoadGroupHandle(udg_Hash, id, 6))
call DestroyEffect(AddSpecialEffect("Abilities\\Weapons\\BallistaMissile\\BallistaMissileTarget.mdl", GetUnitX(u2), GetUnitY(u2)))
call UnitApplyTimedLife( u2, 'BHwe', 0.01 )
call FlushChildHashtable(udg_Hash, id)
call DestroyTimer(t)
call RemoveRect(re)
endif
set t = null
set u1 = null
set u2 = null
set try = null
set e = null
set re = null
set g = null
endfunction 
function Trig_PowerShot_Actions takes nothing returns nothing
local unit r = GetTriggerUnit()
local real f = GetUnitFacing(r)
local real x = GetUnitX(r) + 100 * Cos(f * bj_DEGTORAD)
local real y = GetUnitY(r) + 100 * Sin(f * bj_DEGTORAD)
local real angle = bj_RADTODEG * Atan2(GetSpellTargetY() - y, GetSpellTargetX() - x)
local unit u = CreateUnit(GetOwningPlayer(r), 'h00A', x, y, angle)
local rect re = Rect(x - 150, y - 150, x + 150, y + 150)
local real dist = SquareRoot((GetSpellTargetX() - GetUnitX(r)) * (GetSpellTargetX() - GetUnitX(r)) + (GetSpellTargetY() - GetUnitY(r)) * (GetSpellTargetY() - GetUnitY(r)))
local timer t = CreateTimer()
local integer id = GetHandleId(t)
local group g = CreateGroup()
local group g1 = CreateGroup()
local real d = 100
local real damage = ( 40.00 + ( 80.00 * I2R(GetUnitAbilityLevel(r,'A02L'))  ) )
call SaveUnitHandle(udg_Hash, id, 1, r)
call SaveUnitHandle(udg_Hash, id, 2, u)
call SaveReal(udg_Hash, id, 3, angle)
call SaveReal(udg_Hash, id, 4, dist)
call SaveReal(udg_Hash, id, 5, d)
call SaveGroupHandle(udg_Hash, id, 6, g)
call SaveReal(udg_Hash, id, 7, damage)
call SaveGroupHandle(udg_Hash,id, 8, g1)
call SaveRectHandle(udg_Hash, id, 9, re)
call TimerStart(t, 0.01, true, function Timer_PowerShot )
set u = null
set t = null
set r = null
set g = null
set g1 = null
set re = null
endfunction
//===========================================================================
function InitTrig_PowerShot takes nothing returns nothing
set gg_trg_PowerShot = CreateTrigger(  )
call PlayerUnitEvent( gg_trg_PowerShot, EVENT_PLAYER_UNIT_SPELL_EFFECT, null )
call TriggerAddCondition( gg_trg_PowerShot, Condition( function Trig_PowerShot_Conditions ) )
call TriggerAddAction( gg_trg_PowerShot, function Trig_PowerShot_Actions )
endfunction


Отредактировано Steal nerves, 20.02.2012 в 00:37.
Старый 19.02.2012, 14:51
freest

offline
Опыт: 442
Активность:
Steal_nerves, Nerevar, спасибо именно то, что нужно)
тему клоуз.
Старый 20.02.2012, 04:35
Закрытая тема

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

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

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

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



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