Добавлен
Когда делал некоторые способности у меня появлялись баги, когда что-то не создавалось и/или не двигалось и мне пришла в голову идея, вполне возможно, что баги связаны с использованием цикла (loop) потому что это единственное, что их связывает. Вопрос у меня такой: правильны ли мои догадки и если да, то как решить проблему?
Способность 1
function Trig_PrisonOfSouls_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A006'
endfunction

function Imprisonment takes nothing returns nothing
    local timer ImprisonmentTimer = GetExpiredTimer()
    local integer iid = GetHandleId(ImprisonmentTimer)
    local unit Caster = LoadUnitHandle(udg_hash, iid, StringHash("Caster"))
    local integer id = GetHandleId(Caster)
    local unit Target = LoadUnitHandle(udg_hash, iid, StringHash("Target"))
    local real StartPrisonX = LoadReal(udg_hash, iid, StringHash("StartPrisonX"))
    local real StartPrisonY = LoadReal(udg_hash, iid, StringHash("StartPrisonY"))
    local real TargetX = GetUnitX(Target)
    local real TargetY = GetUnitY(Target)
    local integer soulcount = LoadInteger(udg_hash, id, 1)
    local effect e
    
    if SquareRoot((StartPrisonX - TargetX) * (StartPrisonX - TargetX) + (StartPrisonY - TargetY) * (StartPrisonY - TargetY)) >= 280.0 then
        set e = AddSpecialEffect("Abilities\\Spells\\Human\\ManaFlare\\ManaFlareBoltImpact.mdl", TargetX, TargetY)
        call DestroyEffectTimer(e, 0.5)
        
        call SetUnitPosition(Target, StartPrisonX, StartPrisonY)
        call UnitDamageTarget(Caster, Target, 100 + (5 * soulcount), true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
    else
    endif
    
    set ImprisonmentTimer = null
    set iid = 0
    set Caster = null
    set id = 0
    set Target = null
    set StartPrisonX = 0
    set StartPrisonY = 0
    set TargetX = 0
    set TargetY = 0
    set soulcount = 0
    set e = null
endfunction

function DestroyPrison takes nothing returns nothing
    local unit Prison = GetEnumUnit()
    local integer pid = GetHandleId(Prison)
    local lightning PrisonLightning = LoadLightningHandle(udg_hash, pid, StringHash("Prison Lightning"))
    
    call DestroyLightning(PrisonLightning)
    call RemoveUnit(Prison)
    
    set pid = 0
    set PrisonLightning = null
    set Prison = null
endfunction

function PrisonDamage takes nothing returns nothing
    local timer PrisonDamageTimer = GetExpiredTimer()
    local integer pdid = GetHandleId(PrisonDamageTimer)
    local integer PrisonDamageLoop = LoadInteger(udg_hash, pdid, StringHash("PrisonDamageLoop"))
    local unit Caster = LoadUnitHandle(udg_hash, pdid, StringHash("Caster"))
    local unit Target = LoadUnitHandle(udg_hash, pdid, StringHash("Target"))
    local integer id = GetHandleId(Caster)
    local integer soulcount = LoadInteger(udg_hash, id, 1)
    local unit Dummy
    local timer ImprisonmentTimer = LoadTimerHandle(udg_hash, pdid, StringHash("Imprisonment Timer"))
    local effect e
        
    if PrisonDamageLoop > 0 and IsUnitType(Target, UNIT_TYPE_DEAD) == false then
        call UnitDamageTarget(Caster, Target, 50 + (2.5 * soulcount), true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
        set PrisonDamageLoop = PrisonDamageLoop - 1
        call SaveInteger(udg_hash, pdid, StringHash("PrisonDamageLoop"), PrisonDamageLoop)
        
        set e = AddSpecialEffectTarget("SoulRitual.mdl", Target, "chest")
        call DestroyEffectTimer(e, 0.1)
    else
        call ForGroup(PrisonGroup, function DestroyPrison)
        call DestroyTimer(PrisonDamageTimer)
        call DestroyTimer(ImprisonmentTimer)
        call FlushChildHashtable(udg_hash, pdid)
        call SaveInteger(udg_hash, GetHandleId(Target), StringHash("Prison Boolean"), 0)
    endif
    
    set PrisonDamageTimer = null
    set pdid = 0
    set PrisonDamageLoop = 0
    set Caster = null
    set Target = null
    set id = 0
    set soulcount = 0
    set Dummy = null
    set ImprisonmentTimer = null
    set e = null
endfunction

function RemovePrisonTrigger takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local integer id = GetHandleId(u)
    local trigger t = LoadTriggerHandle(udg_hash, id, StringHash("Remove Texttag"))
    
    call DestroyTrigger(t)
    call ForGroup(PrisonGroup, function DestroyPrison)
    call CastingTimeRemove(u)
    
    set u = null
    set id = 0
    set t = null
endfunction

function Trig_PrisonOfSouls_Actions takes nothing returns nothing
    local unit Caster = GetTriggerUnit()
    local integer cid = GetHandleId(Caster)
    local unit Target = GetSpellTargetUnit()
    local integer tid = GetHandleId(Target)
    local unit Dummy 
    local integer PrisonCreate
    local unit Prison
    local integer pid 
    local lightning PrisonLightning
    local timer PrisonDamageTimer = CreateTimer()
    local integer pdid = GetHandleId(PrisonDamageTimer)
    local real StartPrisonX = GetUnitX(Target)
    local real StartPrisonY = GetUnitY(Target)
    local timer ImprisonmentTimer = CreateTimer()
    local integer iid = GetHandleId(ImprisonmentTimer)
    local trigger t = LoadTriggerHandle(udg_hash, tid, StringHash("Remove Prison"))
    
    if GetUnitTypeId(GetSpellTargetUnit()) != 'u004' then
        set PrisonCreate = 1
        loop
            exitwhen PrisonCreate > 8
            
            set Prison = CreateUnit(GetOwningPlayer(Caster), 'u003', StartPrisonX + 300.00 * Cos((360.00 - 45 * PrisonCreate) * bj_DEGTORAD), StartPrisonY + 300.00 * Sin((360.00 - 45 * PrisonCreate) * bj_DEGTORAD), bj_UNIT_FACING)
            call GroupAddUnit(PrisonGroup, Prison)
            set PrisonLightning = AddLightningEx("DRAB", true, GetUnitX(Prison), GetUnitY(Prison), GetLocationZ(Location(GetUnitX(Prison), GetUnitY(Prison))), StartPrisonX + 315.00 * Cos((315.00 - 45 * PrisonCreate) * bj_DEGTORAD), StartPrisonY + 315.00 * Sin((315.00 - 45 * PrisonCreate) * bj_DEGTORAD), GetLocationZ(Location(StartPrisonX + 315.00 * Cos((315.00 - 45 * PrisonCreate) * bj_DEGTORAD), StartPrisonY + 315.00 * Sin((315.00 - 45 * PrisonCreate) * bj_DEGTORAD))))
            set pid = GetHandleId(Prison)
            call SaveLightningHandle(udg_hash, pid, StringHash("Prison Lightning"), PrisonLightning)
            
            set PrisonCreate = PrisonCreate + 1
        endloop
        
        call SaveInteger(udg_hash, tid, StringHash("Prison Boolean"), 1)
        
        call TimerStart( PrisonDamageTimer, 1.0, true, function PrisonDamage)
        call SaveInteger(udg_hash, pdid, StringHash("PrisonDamageLoop"), 8)
        call SaveUnitHandle(udg_hash, pdid, StringHash("Caster"), Caster)
        call SaveUnitHandle(udg_hash, pdid, StringHash("Target"), Target)
        call SaveTimerHandle(udg_hash, pdid, StringHash("Imprisonment Timer"), ImprisonmentTimer)
        
        call TimerStart( ImprisonmentTimer, 0.05, true, function Imprisonment)
        call SaveReal(udg_hash, iid, StringHash("StartPrisonX"), StartPrisonX)
        call SaveReal(udg_hash, iid, StringHash("StartPrisonY"), StartPrisonY)
        call SaveUnitHandle(udg_hash, iid, StringHash("Caster"), Caster)
        call SaveUnitHandle(udg_hash, iid, StringHash("Target"), Target)
        
        call DestroyTrigger(t)
        set t = CreateTrigger()
        call TriggerRegisterUnitEvent(t, Target, EVENT_UNIT_DEATH)
        call TriggerAddAction(t, function RemovePrisonTrigger)
        call SaveTriggerHandle(udg_hash, tid, StringHash("Remove Prison"), t)
        
        call SaveInteger(udg_hash, tid, StringHash("Prison Boolean"), 1)
        
        //call CastingTime(Target, 8.00)
    else 
        call IssueImmediateOrder( Caster, "stop" )
    endif
    
    set Caster = null
    set cid = 0
    set Target = null
    set tid = 0
    set Dummy = null
    set PrisonCreate = 0
    set Prison = null
    set pid = 0
    set PrisonLightning = null
    set PrisonDamageTimer = null
    set pdid = 0
    set StartPrisonX = 0
    set StartPrisonY = 0
    set ImprisonmentTimer = null
    set iid = 0
endfunction

//===========================================================================
function InitTrig_PrisonOfSouls takes nothing returns nothing
    set gg_trg_PrisonOfSouls = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_PrisonOfSouls, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_PrisonOfSouls, Condition( function Trig_PrisonOfSouls_Conditions ) )
    call TriggerAddAction( gg_trg_PrisonOfSouls, function Trig_PrisonOfSouls_Actions )
endfunction
Способность 2
function AcidSplitFunc takes nothing returns nothing
    local timer ASTimer = GetExpiredTimer()
    
    local effect Alarm = LoadEffectHandle(H, GetHandleId(ASTimer), StringHash("Alarm"))
    
    local effect AcidSplit = LoadEffectHandle(H, GetHandleId(ASTimer), StringHash("AcidSplit"))
    local real ASX = GetEffectX(AcidSplit)
    local real ASY = GetEffectY(AcidSplit)
    
    
    local real AlarmX = LoadReal(H, GetHandleId(ASTimer), StringHash("AlarmX"))
    local real AlarmY = LoadReal(H, GetHandleId(ASTimer), StringHash("AlarmY"))
    
    local real DistanceBetweenNow = SquareRoot((AlarmX - ASX) * (AlarmX - ASX) - (AlarmY - ASY) * (AlarmY - ASY))
    local real a = bj_RADTODEG * Atan2(AlarmY - ASY, AlarmX - ASX)
    local real speed = 2
    local real Distance = LoadReal(H, GetHandleId(ASTimer), StringHash("Distance")) + speed
    local real Height = LoadReal(H, GetHandleId(ASTimer), StringHash("Height"))
    local real StartAndEnd = LoadReal(H, GetHandleId(ASTimer), StringHash("StartAndEnd"))
    local real DistanceBetween = LoadReal(H, GetHandleId(ASTimer), StringHash("DistanceBetween"))
    
    if DistanceBetweenNow > 5.00 then
        call SetEffectX(AcidSplit, ASX + speed * Cos(a * bj_DEGTORAD))
        call SetEffectY(AcidSplit, ASY + speed * Sin(a * bj_DEGTORAD))
        call SetEffectZ(AcidSplit, ParabolaZ2(StartAndEnd, StartAndEnd, Height, DistanceBetween, Distance))
        call BJDebugMsg(R2S(GetEffectZ(AcidSplit)))
    else
        call DestroyEffect(Alarm)
        call DestroyEffect(AcidSplit)
        call DestroyTimer(ASTimer)
        call FlushChildHashtable(H, GetHandleId(ASTimer))
    endif
    
    set ASTimer = null
    set AcidSplit = null
    set Alarm = null
endfunction

function DefilerSpellCast takes nothing returns nothing
    local integer Spell = GetRandomInt(1,1)
    local real PointX 
    local real PointY
    local real a
    local effect Alarm
    local effect AcidSplit
    local integer ASLoop = 0
    local timer ASTimer 
    local real DistanceBetween
    
    if Spell == 1  and GetUnitState(GetTriggerUnit(), UNIT_STATE_MANA) == 100 then
        loop 
            exitwhen ASLoop == 10
            
            set AcidSplit = AddSpecialEffect("Abilities\\Weapons\\ChimaeraAcidMissile\\ChimaeraAcidMissile.mdl", GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()))
            
            set a = GetRandomReal(1, 360)
            
            set PointX = GetUnitX(gg_unit_h000_0070) + GetRandomReal(1, 1000) * Cos(a * bj_DEGTORAD)
            set PointY = GetUnitY(gg_unit_h000_0070) + GetRandomReal(1, 1000) * Sin(a * bj_DEGTORAD)
            
            set Alarm = AddSpecialEffect("Alarm.mdl", PointX, PointY)
            call SetEffectColourR(Alarm, 255)
            call SetEffectColourG(Alarm, 0)
            call SetEffectColourB(Alarm, 0)
            
            set DistanceBetween = SquareRoot((PointX - GetUnitX(GetTriggerUnit())) * (PointX - GetUnitX(GetTriggerUnit())) - (PointY - GetUnitY(GetTriggerUnit())) * (PointY - GetUnitY(GetTriggerUnit())))
            
            set ASTimer = CreateTimer()
            call TimerStart(ASTimer, 0.01, true, function AcidSplitFunc)
            
            call SaveEffectHandle(H, GetHandleId(ASTimer), StringHash("AcidSplit"), AcidSplit)
            call SaveEffectHandle(H, GetHandleId(ASTimer), StringHash("Alarm"), Alarm)
            call SaveReal(H, GetHandleId(ASTimer), StringHash("AlarmX"), PointX)
            call SaveReal(H, GetHandleId(ASTimer), StringHash("AlarmY"), PointY)
            call SaveReal(H, GetHandleId(ASTimer), StringHash("Distanse"), 0)
            call SaveReal(H, GetHandleId(ASTimer), StringHash("Height"), DistanceBetween / 2)
            call SaveReal(H, GetHandleId(ASTimer), StringHash("StartAndEnd"), GetEffectZ(AcidSplit))
            call SaveReal(H, GetHandleId(ASTimer), StringHash("DistanceBetween"), DistanceBetween)
            
            set ASTimer = null 
            
            set ASLoop = ASLoop + 1
        endloop
    endif
    
    call SetUnitState(GetTriggerUnit(), UNIT_STATE_MANA, RMaxBJ(0, 0))
    
    set Alarm = null
    set AcidSplit = null
endfunction

//===========================================================================
function InitTrig_DefilerSpell takes nothing returns nothing
    local trigger defiler = CreateTrigger()
    
    call TriggerRegisterUnitEvent( defiler, gg_unit_n003_0054, EVENT_UNIT_ATTACKED )
    call TriggerAddAction( defiler, function DefilerSpellCast )
    
    set defiler = null
endfunction
В первой способности периодически создаются не все молнии, а во второй двигаются не все эффекты.
`
ОЖИДАНИЕ РЕКЛАМЫ...
23
Похожие вопросы:

ответ
Ярг Восьмой:
nvc123, У него там отсутствует CreateGroup()
А ещё она в заголовке globals не null'ась

Я о group G
ответ
функцию Trig_BlockA_Func005Func011Func001C() убери нафиг
как и другие функции используемые для ифов и подобной херни
а вообще про это написано во всех статьях про jass
мб стоит прочитать сразу несколько статей а затем задавать сюда вопросы?

правила сайта
смотри пункт 10.3
ответ
Хештаблицей будет быстрее:
nvc123:
Extremator:
а что насчёт хештаблиц? Скорость их работы?
всё крайне печально
лол что?
скорость работы глобалок в 1,5 раза быстрее чем у хештейблов
т.е. 10 обращений к хештейблам выполняется столько же времени сколько и 15 к глобалкам
если каждую секунду не выполняется более 1000 обращений к хештейблу то не юзать хэштейблы ради оптимизации та ещё тупость
Да, и для какой цели там сверху стоит "exitwhen true"?
ответ
Ну если много юнитов создавать, особенно тяжелых юнитов вроде героев, то будет пролаг, т.к юниты весьма тяжелые обьекты по меркам движка.
Первый раз созавая юнитов движок будет подгружать все их данные из слк таблиц, что тоже вызывает пролаг.

14
что ты хочешь сделать я не совсем понял твой код
11
это уже готовые способности, в первой через цикл создаётся 8-ми угольник из молний, во второй через цикл создаются эффекты и начинают двигаться.
11
Hate:
может прекратите "обнулять" цифры?
Это старая (относительно) способность, тогда я ещё обнулял цифры)
28
ArhiMEN, я так понимаю это из спеллпака анашина? скинул бы карту тогда, чтобы можно было посмотреть на способности и самому всё исправить

да и вообще тут всё очень страшно и криво, лучше заново переписать

и я говорил, переходи на структуры, они гораздо удобнее и понятнее в исполнении
14
struct sc
	unit caster
	unit dummy
	group g
	real distance
	real angle
		method destroy takes nothing  returns nothing
		call KillUnit(this.dummy)
		call DestroyGroup(this.g)
		set this.caster = null
		set this.dummy = null
		set this.g = null
		call this.destroy()
	endmethod
endstruct
вот что такое структура тут без всякого сохранения и загрузки можно менять значения и все такое очень удобная вещь данный пример можно использовать для способностей типа волна силы

и не нужно по 5-10 раз писать сохранения в хеш таблицу и выгружать их после тика таймера так же одной строкой можно все обнулить кароч плюсов много
Чтобы оставить комментарий, пожалуйста, войдите на сайт.