Добавлен
Да, это снова я, тот самый лох
Доделываю последние штрихи своей абилки, уже теку слюной о том, как становлюсь популярным, все меня хотят, тачки, бабки и т.п., но тут появились они! Утечки! Эти мелкие гадости портя... короче к сути, я не могу понять в чём дело, и т.к. я полный ноль, прошу вас о помощи, пожалуйста. С кодом только практикуюсь, так что обливайте помоями сколько хотите, съем всё, ибо оч голоден :с
Код
scope MySc
globals
private constant integer AbilityID = 'A000' // ID способности
private constant integer DummyID = 'u000' // ID дамми-снаряда

private constant real Damage = 5 // Базовый урон
private constant real DamageLvl = 5 // Доп. урон с прокачкой умения
private constant real DamageScaleStr = 0.25 // Скейл урона от силы
private constant real DamageScaleAgi = 0.50 // Скейл урона от ловкости
private constant real DamageScaleInt = 0.00 // Скейл урона от интеллекта
private constant boolean IncludeBonuses = true // true|false - вкл|выкл бонусы к характеристикам

private constant real DamageRadius = 175 // Радиус урона
private constant real DamageRadiusLvl = 50 // Доп. радиус с прокачкой умения

private constant real DamageInterval = 0.20 // Интервал урона
private constant real ArrowInterval = 0.10 // Интервал спавна стрел

private constant integer DamageWaves = 3 // Кол-во волн
private constant integer DamageWavesLvl = 1 // Доп. кол-во волн с прокачкой умения

private constant real ArrowHeight = 700 // Высота спавна стрел
private constant real ArrowSpeed = 1500 // Скорость падения стрел
private constant real ArrowGround = 0 // Приземление стрелы

private constant attacktype AttackType = ATTACK_TYPE_NORMAL // Тип атаки
private constant damagetype DamageType = DAMAGE_TYPE_NORMAL // Тип урона
private constant weapontype WeaponType = WEAPON_TYPE_WHOKNOWS // Тип оружия (звук)

private constant boolean ArrowEffectTF = false // true|false - вкл|выкл эффекты при попадании волны
private constant string ArrowEffect = "Objects\\Spawnmodels\\Critters\\Albatross\\CritterBloodAlbatross.mdl" // Эффект при попадании волной
private constant string ArrowAttachPoint = "chest" // Точка крепления эффекта
private constant real ArrowEffectRemoveTime = 1.00 // Время удаления эффекта

private real TempReal = 0.
endglobals
//==========================================================================
private function IsUnitDead takes unit u returns boolean
    return IsUnitType(u,UNIT_TYPE_DEAD) or GetUnitTypeId(u) == 0
endfunction

private function filt takes nothing returns boolean // Тут ставим свои условия, кому наносить урон, на данный момент: Юнит жив, Юнит враг применяющему юниту, Юнит не здание
    set bj_lastReplacedUnit = GetFilterUnit()
    return not IsUnitDead(bj_lastReplacedUnit) and IsUnitEnemy(bj_lastReplacedUnit,bj_groupEnumOwningPlayer) and not IsUnitType(bj_lastReplacedUnit,UNIT_TYPE_STRUCTURE)
endfunction

private function remeff takes nothing returns nothing
    local timer t = GetExpiredTimer()
    call DestroyEffect(LoadEffectHandle(udg_Hash,GetHandleId(t),0))
    call FlushChildHashtable(udg_Hash,GetHandleId(t))
    call DestroyTimer(t)
    set t = null
endfunction

private function dmgf takes nothing returns nothing
    local timer t = null
    call UnitDamageTarget(bj_lastCreatedUnit,GetEnumUnit(),TempReal,false,true,AttackType,DamageType,WeaponType)
    if ArrowEffectTF == true then
        set t = CreateTimer()
        set bj_lastCreatedEffect = AddSpecialEffectTarget(ArrowEffect,GetEnumUnit(),ArrowAttachPoint)
        call SaveEffectHandle(udg_Hash,GetHandleId(t),0,bj_lastCreatedEffect)
        call TimerStart(t,ArrowEffectRemoveTime,false,function remeff)
        set t = null
        set bj_lastCreatedEffect = null
    endif
endfunction

private function Arrow takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer i = GetHandleId(t)
    local integer dmgw = LoadInteger(udg_Hash,i,7)
    local integer dmgw1 = LoadInteger(udg_Hash,i,8)
    local real x = LoadReal(udg_Hash,i,1)
    local real y = LoadReal(udg_Hash,i,2)
    local real DI = LoadReal(udg_Hash,i,3)+.01
    local real AI = LoadReal(udg_Hash,i,4)+.01
    local real r = LoadReal(udg_Hash,i,5)
    local real a = 0
    local group g = null
    set bj_groupEnumOwningPlayer = LoadPlayerHandle(udg_Hash,i,6)
    set TempReal = LoadReal(udg_Hash,i,0)
    
    if dmgw1 > dmgw then
        call PauseTimer(t)
        call DestroyTimer(t)
        call FlushChildHashtable(udg_Hash,i)
    else
        if AI >= ArrowInterval then
            set a = GetRandomReal(0,360)
            set bj_lastCreatedUnit = CreateUnit(bj_groupEnumOwningPlayer,DummyID,x+r*Cos(a*bj_DEGTORAD),y+r*Sin(a*bj_DEGTORAD),a)
            call SetUnitFlyHeight(bj_lastCreatedUnit,ArrowHeight,0)
            call SetUnitFlyHeight(bj_lastCreatedUnit,ArrowGround,ArrowSpeed)
            call UnitApplyTimedLife(bj_lastCreatedUnit,'BTLF',(ArrowHeight-ArrowGround)/ArrowSpeed)
            set bj_lastCreatedUnit = null
            set AI = 0.
        endif
        
        if DI >= DamageInterval then
            set g = CreateGroup()
            set bj_lastCreatedUnit = CreateUnit(bj_groupEnumOwningPlayer,DummyID,x,y,0)
            call GroupEnumUnitsInRange(g,x,y,r,Condition(function filt))
            call ForGroup(g,function dmgf)
            call GroupClear(g)
            call DestroyGroup(g)
            call RemoveUnit(bj_lastCreatedUnit)
            set g = null
            set bj_lastCreatedUnit = null
            set DI = 0.
            call SaveInteger(udg_Hash,i,8,dmgw1+1)
        endif
        call SaveReal(udg_Hash,i,3,DI)
        call SaveReal(udg_Hash,i,4,AI)
    endif
    
    set bj_groupEnumOwningPlayer = null
    set t = null
endfunction

private function Actions takes nothing returns nothing
    local unit u = GetSpellAbilityUnit()
    local timer t = CreateTimer()
    local integer i = GetHandleId(t)
    local integer dmgw = DamageWaves+(GetUnitAbilityLevel(u,AbilityID)*DamageWavesLvl)
    local integer dmgw1 = 0
    local real DI = 0.00
    local real AI = 0.00
    local real x = GetSpellTargetX()
    local real y = GetSpellTargetY()
    local real dmg = Damage+(GetUnitAbilityLevel(u,AbilityID)*DamageLvl)+(GetHeroStr(u,IncludeBonuses)*DamageScaleStr)+(GetHeroAgi(u,IncludeBonuses)*DamageScaleAgi)+(GetHeroInt(u,IncludeBonuses)*DamageScaleInt)
    local real r = DamageRadius+(GetUnitAbilityLevel(u,AbilityID)*DamageRadiusLvl)
    
    set bj_groupEnumOwningPlayer = GetOwningPlayer(u)
    call SaveReal(udg_Hash,i,0,dmg)
    call SaveReal(udg_Hash,i,1,x)
    call SaveReal(udg_Hash,i,2,y)
    call SaveReal(udg_Hash,i,3,DI)
    call SaveReal(udg_Hash,i,4,AI)
    call SaveReal(udg_Hash,i,5,r)
    call SavePlayerHandle(udg_Hash,i,6,bj_groupEnumOwningPlayer)
    call SaveInteger(udg_Hash,i,7,dmgw)
    call SaveInteger(udg_Hash,i,8,dmgw1)
    call TimerStart(t,.01,true,function Arrow)
    
    set bj_groupEnumOwningPlayer = null
    set u = null
    set t = null
endfunction

//===========================================================================
private function Conditions takes nothing returns boolean
    return GetSpellAbilityId() == AbilityID
endfunction

function InitTrig_Phoenix takes nothing returns nothing // Phoenix переименовать на название твоего триггера
    local trigger t = CreateTrigger()
    local integer index = 0
    loop
        call TriggerRegisterPlayerUnitEvent(t,Player(index),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition(t,Condition(function Conditions))
    call TriggerAddAction(t,function Actions)
    set t = null
endfunction
endscope
Прикладываю карту, если это имеет значение
Upd: нашел одну ошибку, добавил set t = null в самом конце
Upd: убрал private constant real DamageRadiusThreshold = 50, без понятия зачем добавлял

Разобрался в чём дело. Может там где-то что-то и не донулил, но основная причина утечек из-за триггеров d1 и d2
Способность выложил у себя в блоге, там буду её обновлять (если это почему-то интересно)
Загруженные файлы
`
ОЖИДАНИЕ РЕКЛАМЫ...
32
А как насчет карту без кастом гуи выложить, то не открывается в редакторе...

Вот это:
function remeff takes nothing returns nothing
    local timer t = GetExpiredTimer()
    set bj_lastCreatedEffect = LoadEffectHandle(udg_Hash,GetHandleId(t),0)
    call DestroyEffect(bj_lastCreatedEffect)
    call FlushChildHashtable(udg_Hash,GetHandleId(t))
    call DestroyTimer(t)
    set t = null
    set bj_lastCreatedEffect = null
endfunction
Можно заменить на это
function remeff takes nothing returns nothing
    local timer t = GetExpiredTimer()
    call DestroyEffect(LoadEffectHandle(udg_Hash,GetHandleId(t),0))
    call FlushChildHashtable(udg_Hash,GetHandleId(t))
    call DestroyTimer(t)
    set t = null
endfunction

Потом падение внезапно можно сделать и попроще.
28
А как насчет карту без кастом гуи выложить, то не открывается в редакторе...
quq_CCCP, кастом гуи это кастом скрипт что-ли?
Конвертировал в код этот триггер, надеюсь теперь всё ок

Потом падение внезапно можно сделать и попроще.
В смысле, падение стрел можно сделать проще? По моему там и так всё максимально тупо и примитивно. Или ты про урон волн?

А, я походу понял о чём ты, теперь должно быть всё норм
Загруженные файлы
32
rsfghd, внезапно можно закаказать кастом модель падающих стрелл (да и где то я это уже видел), ну а урон наносить триггерно через 1 сек, как у огненного голема или звездопада.
28
quq_CCCP, сейчас я просто испытываю свои возможности, учусь новому и т.д., одним словом клипаю велосипеды
Да и в принципе прикольно, что можно впихнуть абсолютно любую модельку, ничего заказывать даже не нужно

К тому же я планировал сделать возможность появления стрел как у бурана, и чтобы угол падения можно было редактировать
28
Разобрался в чём дело. Может там где-то что-то и не донулил, но основная причина утечек из-за триггеров d1 и d2
Способность выложил у себя в блоге, там буду её обновлять (если это почему-то интересно)
Загруженные файлы
Принятый ответ
Чтобы оставить комментарий, пожалуйста, войдите на сайт.