Алгоритмы, Наработки и Способности
Способ реализации:
Jass
Тип:
Наработка
И так, система снаряда с настройками, что она включает в себя
  1. Настраивымый урон, можно так же улучшать за каждый уровень (Дальность, скорость, урон, радиус урона, умножитель)
  2. Настраивымый урон от характеристик можно Включить\Отключить
  3. Настройка умножителся урона от характеристик тоже можно Включить\Отключить
  4. Настройка урона в виде Включить\Отключить доп.характеристики(зеленые)
  5. Оглушение, она не требует доп.дамми юнита с абилкой стана(стан через триггер сделан)
  6. Возможность создавать эффекты при полете так же можно Включить\Отключить
  7. Возможность создавать эффект из дамми юнитов можно Включить\Отключить
  8. Возможность создать эффект прикрепленный к юниту(врагу\союзнику) можно Включить\Отключить
  9. Возможность настроить урон под себя (Атака, урон, оружие)
  10. выбирать цель Враг\Союзник
  11. наносить урон или лечить можно включить обеих
  12. Возможность настроить длительность подготовки спела(каст тайм)
  13. Возможность изменять создавамые эффект в точ числе и эффект оглушения
  14. Возможность изменять точку крепления
  15. Возможность Включить\Отключить лечение самого героя
Утечек нет, и багов не нашел пока сам проверял, если хотите изменить систему под себя пишите в лс
Система очень гибкая и очень легко настроить под себя
Код
library MissleSystem initializer Init
/*

PerLevel_Stats - Улучшает характеристики способности с каждым новым уровнем

AddPercentage - Умножает характеристик героя при урон\лечении

includeBonus - Добавляет к значению урона\лечении характеристики, если AddPercentage включен то добавляет с умножителем

Condition_Enemy - Способность выбирает юнита если он враг

Condition_Ally - Способность выбирает юнита если он союзник

DummyEffect - На данном примере я использовал дамми юнита как эффект если вы не делаете этого отключите

FlyEffect - Создает эффект на земле с ним нельзя что либо сделать

AllyEffectPosition - Создает эффект на позиции союзника который попал под способность

AllyEffectTarget - Создает эффект на теле союзника который попал под способность. Пример: "origin" =  у ног, "overhead" = над головой

EnemyEffectPosition - Создает эффект на позиции врага который попал под способность

EnemyEffectTarget - Создает эффект на теле врага который попал под способность. Пример: "origin" =  у ног, "overhead" = над головой

HealHero - По умолчанию способность не лечит самого героя - кастера если это включено то будет лечить

*/

    globals
        private constant hashtable Hash = InitHashtable()
        
        private integer SpellId = 'A000'         //Способность пустышка
        private integer DummyId = 'd000'         //Дамми Стрела
        private integer DummyEffectId = 'd001'   //Эффект Волна
        
        private boolean PerLevel_Stats = true  //Включать ли? Улучшение хар-ик способности за уровень || Да - true || Нет - false||
        private boolean AddPercentage = false  //Включать ли? Умножитель хар-ик для героя урона       || Да - true || Нет - false||
        private boolean includeBonus = false   //Включать ли? Дополнительный урон от хар-ик героя     || Да - true || Нет - false||
        
        private real Default_Damage = 60.0     //Урон по умолчанию
        private real Default_Percentage = 4.50 //Умножитель хар-ик героя по умолчанию
        private real Default_Range = 1200.0    //Дальность по умолчанию
        private real Default_Speed = 30.0      //Скорость по умолчанию
        private real Default_Radius = 150.0    //Радиус урона по умолчанию
        
        private real PerLevel_Damage = 60.0     //Дополнительный урон за уровень
        private real PerLevel_Percentage = 0.00 //Умножитель хар-ик героя за уровень
        private real PerLevel_Range = 100.0     //Дополнительная дальность за уровень
        private real PerLevel_Speed = 0.0       //Дополнительная скорость за уровень
        private real PerLevel_Radius = 0.0      //Дополнительная дистанция урона за уровень
         
        private boolean includeStr = false     //Включать ли?  Силу героя для урона       || Да - true || Нет - false||
        private boolean includeAgi = false     //Включать ли?  Ловкость героя для урона   || Да - true || Нет - false||
        private boolean includeInt = false     //Включать ли?  Интеллект героя для урона  || Да - true || Нет - false||
        
        private boolean includeStrAdd = false  //Включать ли?  Дополнительную силу(зеленую)          || Да - true || Нет - false||
        private boolean includeAgiAdd = false  //Включать ли?  Дополнительную ловкость(зеленую)      || Да - true || Нет - false||
        private boolean includeIntAdd = false  //Включать ли?  Дополнительную интеллект(зеленую)     || Да - true || Нет - false||
        
        private attacktype AttackType = ATTACK_TYPE_MAGIC         //Тип атаки
        private damagetype DamageType = DAMAGE_TYPE_MAGIC         //Тип урона
        private weapontype WeaponType = WEAPON_TYPE_WHOKNOWS      //Тип оружия

        private boolean Condition_Enemy = true                 //Цель Враг?                    || Да - true || Нет - false||
        private boolean Condition_Ally = true                  //Цель Союзник?                 || Да - true || Нет - false||
        
        private boolean DamageType_Heal = true                 //Лечить союзников?             || Да - true || Нет - false||
        private boolean DamageType_Damage = true               //Наносить урон врагам?         || Да - true || Нет - false||
        
        private boolean DummyEffect = true                     //Эффект сделан из Дамми юнита? || Да - true || Нет - false||
        private real DummyEffectLifeTime = 1.5                 //Время жизни Дамми юнита если он эффект
        
        private boolean FlyEffect = false                                                               //Вкличить ли? Эффект полета  || Да - true || Нет - false||
        private string FlyEffectName = "Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl"          //Название эффекта полета. Внимание! Должно быть 2х "\"
        
        private boolean AllyEffectPosition = false                                                      //Создать ли? На позиции      || Да - true || Нет - false||
        private boolean AllyEffectTarget = true                                                         //Крепить ли? К телу          || Да - true || Нет - false||
        private string AllyEffectName = "Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl"    //Название эффекта лечения. Внимание! Должно быть 2х "\"
        private string AllyEffectAttachmentPoint = "origin"                                             //Название точки крипления эффекта
        
        private boolean EnemyEffectPosition = false                                                     //Создать ли? На позиции      || Да - true || Нет - false||
        private boolean EnemyEffectTarget = true                                                        //Крепить ли? К телу          || Да - true || Нет - false||
        private string EnemyEffectName = "Abilities\\Spells\\Undead\\DeathCoil\\DeathCoilSpecialArt.mdl"//Название эффекта урона. Внимание! Должно быть 2х "\"
        private string EnemyEffectAttachmentPoint = "chest"                                             //Название точки крипления эффекта
        
        private boolean HealHero = false        //Лечить ли самого героя?

        private real CastTime = 0.10            //Длительность применения способности

        private unit TempCaster
        private unit TempUnit
        
        private real TempDamage
        
        private group TempGroup = CreateGroup()
        private group SecondGroup
        
        private trigger MissleSystem = CreateTrigger(  )
    endglobals

    private function MissleSystem_Filter_Units takes nothing returns boolean
        return GetWidgetLife(GetFilterUnit()) > 0.405 and not IsUnitInGroup(GetFilterUnit(),SecondGroup) 
    endfunction

    private function MissleSystem_Action_Damage takes nothing returns nothing
        local unit Enum = GetEnumUnit()
        
        if DamageType_Heal and IsUnitAlly(Enum,GetOwningPlayer(TempCaster)) and Condition_Ally and not (Enum == TempCaster) then
        
            if HealHero then
                call SetUnitState(TempCaster,UNIT_STATE_LIFE,GetWidgetLife(Enum) + TempDamage)
            endif
            
            call SetUnitState(Enum,UNIT_STATE_LIFE,GetWidgetLife(Enum) + TempDamage)
            
            
            if AllyEffectName != "" then
            
                if AllyEffectPosition then
                    call DestroyEffect(AddSpecialEffect(AllyEffectName,GetUnitX(Enum),GetUnitY(Enum)))
                elseif AllyEffectTarget then
                    call DestroyEffect(AddSpecialEffectTarget(AllyEffectName,Enum,AllyEffectAttachmentPoint))
                endif
                
            endif
            
        endif
        
        if DamageType_Damage and not IsUnitAlly(Enum,GetOwningPlayer(TempCaster)) and Condition_Enemy then
            call UnitDamageTarget(TempCaster,Enum,TempDamage,false,false,ATTACK_TYPE_MAGIC,DAMAGE_TYPE_MAGIC,null)
            
            if EnemyEffectName != "" then
            
                if EnemyEffectPosition then
                    call DestroyEffect(AddSpecialEffect(EnemyEffectName,GetUnitX(Enum),GetUnitY(Enum)))
                elseif EnemyEffectTarget then
                    call DestroyEffect(AddSpecialEffectTarget(EnemyEffectName,Enum,EnemyEffectAttachmentPoint))
                endif
                
            endif
            
        endif
        
        call GroupAddUnit(SecondGroup,Enum)
        
        set Enum = null
    endfunction

    private function MissleSystem_Action_Flyig takes nothing returns nothing
        local timer Timer = GetExpiredTimer()
        local integer HandleId = GetHandleId(Timer)
        
        local unit Caster = LoadUnitHandle(Hash,HandleId,StringHash("Caster"))
        
        local unit Dummy = LoadUnitHandle(Hash,HandleId,StringHash("Dummy"))
        
        local real Angle = LoadReal(Hash,HandleId,StringHash("Angle"))
        
        local real Distance = LoadReal(Hash,HandleId,StringHash("Distance"))
        
        local real Speed = LoadReal(Hash,HandleId,StringHash("Speed"))
        
        local real Radius = LoadReal(Hash,HandleId,StringHash("Radius"))
        
        local real Damage = LoadReal(Hash,HandleId,StringHash("Damage"))
        
        local group Group = LoadGroupHandle(Hash,HandleId,StringHash("Group"))
        
        local real xDummy = GetUnitX(Dummy)
        local real yDummy = GetUnitY(Dummy)
        
        local real xCondition = xDummy + Speed * Cos(Angle)
        local real yCondition = yDummy + Speed * Sin(Angle)
        
        if Distance > 50 and not IsTerrainPathable(xCondition,yCondition,PATHING_TYPE_FLYABILITY)
            
            set TempCaster = Caster
            set TempDamage = Damage
            set SecondGroup = Group
            
            call GroupEnumUnitsInRange(TempGroup,xDummy,yDummy,Radius,Condition(function MissleSystem_Filter_Units))
            
            call ForGroup(TempGroup,function MissleSystem_Action_Damage)
            
            call GroupClear(TempGroup)
            
            if DummyEffect then
                set bj_lastCreatedUnit = CreateUnit(GetOwningPlayer(Caster),DummyEffectId,xDummy,yDummy,Rad2Deg(Angle))
                
                call UnitApplyTimedLife(bj_lastCreatedUnit, 'BTLF', DummyEffectLifeTime)
            endif
            
            call SetUnitX(Dummy,xDummy + Speed * Cos(Angle))
            call SetUnitY(Dummy,yDummy + Speed * Sin(Angle))
            
            call SaveReal(Hash,HandleId,StringHash("Distance"),Distance - Speed)
            
        else
            
            call PauseTimer(Timer)
            
            call DestroyGroup(Group)
            
            call KillUnit(Dummy)
            
            call FlushChildHashtable(Hash,HandleId)
            
            call DestroyTimer(Timer)
            
        endif
        
        set Timer = null
        set Caster = null
        set Dummy = null
        set Group = null
        
    endfunction

    private function MissleSystem_Action_Init takes nothing returns nothing
        local timer Timer = CreateTimer()
        local integer HandleId = GetHandleId(Timer)
        
        local unit Caster = GetTriggerUnit()
        
        local group Group = CreateGroup()
        
        local real xCaster = GetUnitX(Caster)
        local real yCaster = GetUnitY(Caster)
        
        local real xPoint = GetSpellTargetX()
        local real yPoint = GetSpellTargetY()
        
        local real Angle = Atan2(yPoint - yCaster, xPoint - xCaster)
        
        local unit Dummy = CreateUnit(GetOwningPlayer(Caster),DummyId,xCaster,yCaster,Rad2Deg(Angle))
        
        local integer Level = GetUnitAbilityLevel(Caster,SpellId)
        
        local real Damage
        local real Distance
        local real Speed
        local real Radius
        local real Percentage
        
        if PerLevel_Stats then
        
            set Damage = Default_Damage + (PerLevel_Damage * Level)
            
            set Percentage = Default_Percentage + (PerLevel_Percentage * Level)
            
            set Distance = Default_Range + (PerLevel_Range * Level)
            
            set Speed = Default_Speed + (PerLevel_Speed * Level)
            
            set Radius = Default_Radius + (PerLevel_Radius * Level)
            
        else

            set Distance = Default_Range
            set Speed = Default_Speed
            set Radius = Default_Radius
            set Damage = Default_Damage
            
        endif
        
        if includeBonus then
            //===========================================================================
                if includeStr then
        
                    if AddPercentage then
                
                        set Damage = Damage + (GetHeroStr(Caster,includeStrAdd) * Percentage )
                        
                    else
                    
                        set Damage = Damage + GetHeroStr(Caster,includeStrAdd)
                    
                    endif
            
                endif
            //===========================================================================
                if includeAgi then
                
                    if AddPercentage then
                
                        set Damage = Damage + (GetHeroAgi(Caster,includeAgiAdd) * Percentage )
                        
                    else
                    
                        set Damage = Damage + GetHeroAgi(Caster,includeAgiAdd)
                    
                    endif
            
                endif
            //===========================================================================
                if includeInt then
                
                    if AddPercentage then
                
                        set Damage = Damage + (GetHeroInt(Caster,includeIntAdd) * Percentage )
                        
                    else
                    
                        set Damage = Damage + GetHeroInt(Caster,includeIntAdd)
                    
                    endif
            
                endif
            //===========================================================================
        endif

        call SetUnitVertexColor(Dummy,255,255,255,0)
        
        call SaveUnitHandle(Hash,HandleId,StringHash("Caster"),Caster)
        call SaveUnitHandle(Hash,HandleId,StringHash("Dummy"),Dummy)
        
        call SaveReal(Hash,HandleId,StringHash("Angle"),Angle)
        call SaveReal(Hash,HandleId,StringHash("Distance"),Distance)
        call SaveReal(Hash,HandleId,StringHash("Speed"),Speed)
        call SaveReal(Hash,HandleId,StringHash("Damage"),Damage)
        call SaveReal(Hash,HandleId,StringHash("Radius"),Radius)
        
        call SaveGroupHandle(Hash,HandleId,StringHash("Group"),Group)
        
        call TriggerSleepAction(CastTime)
        
        call SetUnitVertexColor(Dummy,255,255,255,255)
        
        call TimerStart(Timer,0.015625,true,function MissleSystem_Action_Flyig)
        
        set Timer = null
        set Caster = null
        set Dummy = null
        set Group = null
        
    endfunction

    private function MissleSystem_Condition takes nothing returns boolean
        return GetSpellAbilityId() == SpellId
    endfunction

    private function Init takes nothing returns nothing
        local integer index = 0

        loop
            call TriggerRegisterPlayerUnitEvent(MissleSystem, Player(index), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)

            set index = index + 1
            exitwhen index == bj_MAX_PLAYER_SLOTS
        endloop

        call TriggerAddCondition( MissleSystem, Condition( function MissleSystem_Condition ) )
        call TriggerAddAction( MissleSystem, function MissleSystem_Action_Init )
    endfunction

endlibrary
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
14
Обновил систему теперь там еще больше настроек и пехотинцы с 5000 хп для теста для тех кто хочет потестить систему по полной...
14
Исправил ошибку с созданием эффекта при полете
28
under11, не в этом дело, для демонстрации нужно всегда закидывать счётчик хэндлов и показатель сколько урона нанесено
14
Сегодня попробую сделать целевую способность с искусственным станом дабы избежать создание дамми кастера
14
как думаете стоит ли делать систему для целевых способностей?
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.