Добавлен , опубликован
Дисклеймер!
Я полный нуб/лох/помойка в джассе (называйте как хотите), ничего толком не знаю и короче юзай способность на свой страх и риск. По возможности буду стараться оптимизировать это говно
Предложения по улучшению пишите в комменты
Если ты пришел сюда с вопроса Вопрос по группам джасс, то я так понимаю ты ценитель низкой культуры? Похвально. Держи противогаз, вот фильтр к нему, если ты готов, то сейчас начнётся мясо. Умрёшь во время прочтения этого высера - страховку не оплачиваю
Цель: точка или боевая единица
Тип: АОЕ урон
Суть: спавнятся ряды огромных вонючих волн, от которых всё живое гибнет к чертям собачьим, остальное можно прочитать в настройках
Подходит как для обычного юнита, так и для героя
Карта в комментах
Текущие настройки:
  • Название своей хэш-таблицы
  • ID способности
  • ID дамми-снаряда
  • Кол-во линий волн
  • Доп. кол-во линий волн с уровнем
  • Количество дамми в линии волны
  • Доп. кол-во дамми в линии волны с уровнем
  • Интервал появления волн
  • Радиус урона волны
  • Базовый урон волны
  • Доп. урон волны с уровнем
  • Скейл урона от силы
  • Скейл урона от ловкости
  • Скейл урона от интеллекта
  • вкл|выкл бонусы к характеристикам
  • Тип атаки
  • Тип урона
  • Тип оружия (звук)
  • Скорость волн
  • Дистанция прохождения линии волн
  • Доп. дистанция прохождения линии волн с уровнем
  • Появление линии волн за применяющим юнитом
  • Доп. дистанция появления линии волн за применяющим юнитом с уровнем
  • Дистанция между дамми
  • Сила отбрасывания
  • Время отбрасывания
  • вкл|выкл отбрасывание
  • Минимальная высота волны
  • Максимальная высота волны
  • Время, за которое волна достигнет максимальной высоты
  • вкл|выкл эффекты при попадании
  • Эффект при попадании
  • Точка крепления эффекта
  • Время удаления эффекта
Код
scope MySc
define
private H = udg_Hash // Название твоей хэш-таблицы (использованы лишь таймеры)
private AbilityID = 'A000' // ID способности
private DummyID = 'u000' // ID дамми-юнита

private Wave = 2 // Кол-во цунами
private WaveLvl = 1 // Доп. кол-во цунами с уровнем
private Waves = 3 // Количество волн
private WavesLvl = 1 // Доп. кол-во волн с уровнем
private WaveInterval = 1.00 // Интервал появления цунами

private WaveRadius = 200.00 // Радиус урона волны
private WavesDamage = 50.00 // Базовый урон волны
private WavesDamageLvl = 50.00 // Доп. урон волны с уровнем
private DamageScaleStr = 0.00 // Скейл урона от силы
private DamageScaleAgi = 0.00 // Скейл урона от ловкости
private DamageScaleInt = 1.00 // Скейл урона от интеллекта
private IncludeBonuses = true // true|false - вкл|выкл бонусы к характеристикам

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

private WavesSpeed = 500.00 /* Скорость цунами */ *0.03

private WaveDistanceForward = 700.00 // Дистанция прохождения цунами
private WaveDistanceForwardLvl = 300.00 // Доп. дистанция прохождения цунами с уровнем
private WaveDistanceBack = 350.00 // Появление цунами за применяющим юнитом
private WaveDistanceBackLvl = 150.00 // Доп. дистанция появления цунами за применяющим юнитом с уровнем
private DistanceBetweenWaves = 200.00 // Дистанция между волнами

private WaveDiscarding = 2.50 /* Сила отбрасывания */ *3
private WaveDiscardingTime = 1.00 // Время отбрасывания
private WaveDiscardingTF = 0 // 0|1 - вкл|выкл отбрасывание

private HeightWaveMin = 1.00 // Минимальная высота цунами (не ставить меньше 1.00)
private HeightWaveMax = 50.00 // Максимальная высота волны
private HeightWaveFreq = 0.583 // Время, за которое цунами достигает максимальной высоты

private WaveVisSpeed = 2.55 // Скорость появления/затухания цунами (255/время*0.01) (поставь 0.00, чтобы выключить)

private EffectTF = 0 // 0|1 - вкл|выкл эффекты при попадании волны
private Effect = "Abilities\\Spells\\Other\\CrushingWave\\CrushingWaveDamage.mdl" // Эффект при попадании волной
private AttachPoint = "origin" // Точка крепления эффекта
private EffectRemoveTime = 1.00 // Время удаления эффекта
enddefine
globals
private real TempReal
endglobals
//==========================================================================
private function IsUnitDead takes unit u returns boolean
    return IsUnitType(u,UNIT_TYPE_DEAD) or GetUnitTypeId(u) == 0
endfunction

private function myfilt 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_FLYING)
endfunction

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

private function CopyGroup takes group g returns group
    set bj_groupAddGroupDest = CreateGroup()
    call ForGroup(g, function GroupAddGroupEnum)
    return bj_groupAddGroupDest
endfunction

private function OddEven takes integer i returns boolean
    local integer ii = 0
    loop
        exitwhen ii >= i
        set ii = ii + 2
    endloop
    if ii != i then
        return true
    endif
    return false
endfunction

private function visg takes nothing returns nothing
    call SetUnitVertexColor(GetEnumUnit(),255,255,255,R2I(TempReal))
endfunction

private function visg1 takes nothing returns nothing
    call SetUnitVertexColor(GetEnumUnit(),255,255,255,255-R2I(TempReal))
endfunction

private function wavv takes nothing returns nothing
    call SetUnitVertexColor(GetEnumUnit(),255,255,255,0)
endfunction

private function vis takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer i = GetHandleId(t)
    local group g = LoadGroupHandle(H,i,0)
    local real r = LoadReal(H,i,1)+WaveVisSpeed
    local integer tf = LoadInteger(H,i,2)
    
    if r > 255 then
        if LoadInteger(H,i,2) != 1 then
            call GroupClear(g)
            call DestroyGroup(g)
        endif
        
        call PauseTimer(t)
        call DestroyTimer(t)
        call FlushChildHashtable(H,i)
    else
        set TempReal = r
        if tf == 0 then
            call ForGroup(g,function visg)
        else
            call ForGroup(g,function visg1)
        endif
        call SaveReal(H,i,1,r)
    endif
    
    set g = null
    set t = null
endfunction

private function wav takes player p, real x, real y, real a, real aa, group g, integer w returns nothing
    local real d = DistanceBetweenWaves
    local group gg = null
    local timer t = null
    local integer i = 0
    local integer ii = 0
    if WaveVisSpeed > 0.00 then
        set gg = CreateGroup()
        set t = CreateTimer()
    endif
    
    if OddEven(w) then
        set bj_lastCreatedUnit = CreateUnit(p,DummyID,x,y,a)
        call GroupAddUnit(g,bj_lastCreatedUnit)
        call SetUnitFlyHeight(bj_lastCreatedUnit,HeightWaveMin,0)
        if WaveVisSpeed > 0.00 then
            call GroupAddUnit(gg,bj_lastCreatedUnit)
        endif
        set bj_lastCreatedUnit = null
        set i = i + 1
    else
        set d = d/2
    endif
   
    loop
        exitwhen i == w
        if not OddEven(i) then
            set bj_lastCreatedUnit = CreateUnit(p,DummyID,x+d*Cos((a-90)*bj_DEGTORAD),y+d*Sin((a-90)*bj_DEGTORAD),a)
        else
            set bj_lastCreatedUnit = CreateUnit(p,DummyID,x+d*Cos((a+90)*bj_DEGTORAD),y+d*Sin((a+90)*bj_DEGTORAD),a)
        endif
        call SetUnitFlyHeight(bj_lastCreatedUnit,HeightWaveMin,0)
        call GroupAddUnit(g,bj_lastCreatedUnit)
        if WaveVisSpeed > 0.00 then
            call GroupAddUnit(gg,bj_lastCreatedUnit)
        endif
        call SetUnitPathing(bj_lastCreatedUnit,false)
        set bj_lastCreatedUnit = null
        set i = i+1
        if ii == 0 then
            set ii = 1
        else
            set ii = 0
            set d = d+DistanceBetweenWaves
        endif
    endloop

    if WaveVisSpeed > 0.00 then
        call ForGroup(gg,function wavv)
        call SaveGroupHandle(H,GetHandleId(t),0,gg)
        call TimerStart(t,0.01,true,function vis)
        set gg = null
        set t = null
    endif
endfunction

private function kill takes nothing returns nothing
    call KillUnit(GetEnumUnit())
endfunction

private function move1 takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer i = GetHandleId(t)
    local unit u = LoadUnitHandle(H,i,0)
    local real a = LoadReal(H,i,1)
    local real d = LoadReal(H,i,2)
    local real tm = LoadReal(H,i,3)+0.03
    
    if tm > WaveDiscardingTime then
        call PauseTimer(t)
        call DestroyTimer(t)
        call FlushChildHashtable(H,i)
    else
        call SetUnitX(u,GetUnitX(u)+d*Cos(a))
        call SetUnitY(u,GetUnitY(u)+d*Sin(a))
        call SaveReal(H,i,2,d-(WaveDiscarding/WaveDiscardingTime*0.03))
        call SaveReal(H,i,3,tm)
    endif
    
    set t = null
    set u = null
endfunction

private function move takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local timer tt = null
    local integer i = GetHandleId(t)
    local group g = LoadGroupHandle(H,i,0)
    local group gg = CopyGroup(g)
    local group ggg = CreateGroup()
    local group g1 = LoadGroupHandle(H,i,4)
    local real d = LoadReal(H,i,2)+WavesSpeed
    local real a
    local unit u = null
    local unit uu = null
    
    if WaveVisSpeed > 0.00 then
        set TempReal = (WavesSpeed/3)*(255/WaveVisSpeed)
        if TempReal > LoadReal(H,i,1)-d and LoadInteger(H,i,13) == 0 then
            set tt = CreateTimer()
            call SaveGroupHandle(H,GetHandleId(tt),0,g)
            call SaveInteger(H,GetHandleId(tt),2,1)
            call TimerStart(tt,0.01,true,function vis)
            set tt = null
            call SaveInteger(H,i,13,1)
        endif
    endif

    loop
        set u = FirstOfGroup(gg)
        exitwhen u == null
        set a = GetUnitFacing(u)*bj_DEGTORAD

        call SetUnitX(u,GetUnitX(u)+WavesSpeed*Cos(a))
        call SetUnitY(u,GetUnitY(u)+WavesSpeed*Sin(a))
        
        if LoadInteger(H,i,6) == 0 and d <= LoadReal(H,i,1)-(HeightWaveMax*2) then
            call SetUnitFlyHeight(u,GetUnitFlyHeight(u)+LoadReal(H,i,5),0)
            if GetUnitFlyHeight(u) >= HeightWaveMax then
                call SaveInteger(H,i,6,1)
            endif
        elseif GetUnitFlyHeight(u) > HeightWaveMin then
            call SetUnitFlyHeight(u,GetUnitFlyHeight(u)-LoadReal(H,i,5),0)
            if GetUnitFlyHeight(u) <= HeightWaveMin then
                call SaveInteger(H,i,6,0)
            endif
        endif
        
        set bj_groupEnumOwningPlayer = GetOwningPlayer(u)
        call GroupEnumUnitsInRange(ggg,GetUnitX(u),GetUnitY(u),WaveRadius,Condition(function myfilt))
        set bj_groupEnumOwningPlayer = null
        loop
            set uu = FirstOfGroup(ggg)
            exitwhen uu == null
            if not IsUnitInGroup(uu,g1) then
                call UnitDamageTarget(u,uu,LoadReal(H,i,3),true,false,AttackType,DamageType,WeaponType)
                call GroupAddUnit(g1,uu)
                if WaveDiscardingTF == 0 and not IsUnitType(uu,UNIT_TYPE_STRUCTURE) then
                    set tt = CreateTimer()
                    call SaveUnitHandle(H,GetHandleId(tt),0,uu)
                    call SaveReal(H,GetHandleId(tt),1,a)
                    call SaveReal(H,GetHandleId(tt),2,WaveDiscarding)
                    call TimerStart(tt,0.03,true,function move1)
                    set tt = null
                endif
                if EffectTF == 0 then
                    set tt = CreateTimer()
                    call SaveEffectHandle(H,GetHandleId(tt),0,AddSpecialEffectTarget(Effect,uu,AttachPoint))
                    call TimerStart(tt,EffectRemoveTime,false,function remeff)
                    set tt = null
                endif
            endif
            call GroupRemoveUnit(ggg,uu)
            set uu = null
        endloop
        call GroupRemoveUnit(gg,u)
        set u = null
    endloop
    
    if d >= LoadReal(H,i,1) then
        call PauseTimer(t)
        call DestroyTimer(t)
        call FlushChildHashtable(H,i)
        call ForGroup(g,function kill)
        call GroupClear(g)
        call DestroyGroup(g)
        call GroupClear(g1)
        call DestroyGroup(g1)
    else
        call SaveReal(H,i,2,d)
    endif
    
    call DestroyGroup(gg)
    call DestroyGroup(ggg)
    set g = null
    set gg = null
    set ggg = null
    set g1 = null
    set t = null
    set g = null
endfunction

private function wvs takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer i = GetHandleId(t)
    local integer lvl = LoadInteger(H,i,11)
    local integer w = LoadInteger(H,i,6)+1
    local unit u = LoadUnitHandle(H,i,12)
    local real a = LoadReal(H,i,7)
    local real aa = LoadReal(H,i,8)
    local real x = LoadReal(H,i,9)
    local real y = LoadReal(H,i,10)
    local group g = null
    
    if w == Wave+(WaveLvl*lvl) or IsUnitDead(u) then
        call PauseTimer(t)
        call DestroyTimer(t)
        call FlushChildHashtable(H,i)
    else
        call SaveInteger(H,i,6,w)
        set t = null
        set t = CreateTimer()
        set i = GetHandleId(t)
        set g = CreateGroup()
        call wav(GetOwningPlayer(u),x+(WaveDistanceBack+(WaveDistanceBackLvl*lvl))*Cos(aa),y+(WaveDistanceBack+(WaveDistanceBackLvl*lvl))*Sin(aa),a,aa,g,Waves+(WavesLvl*lvl))
        call SaveGroupHandle(H,i,0,g)
        call SaveReal(H,i,1,WaveDistanceForward+(WaveDistanceForwardLvl*lvl))
        call SaveReal(H,i,3,WavesDamage+(lvl*WavesDamageLvl)+(GetHeroStr(u,IncludeBonuses)*DamageScaleStr)+(GetHeroAgi(u,IncludeBonuses)*DamageScaleAgi)+(GetHeroInt(u,IncludeBonuses)*DamageScaleInt))
        call SaveGroupHandle(H,i,4,CreateGroup())
        call SaveReal(H,i,5,(HeightWaveMax-HeightWaveMin)/HeightWaveFreq*0.03)
        call TimerStart(t,0.03,true,function move)
        set g = null
    endif
    
    set u = null
    set t = null
endfunction

private function Actions takes nothing returns nothing
    local timer t = CreateTimer()
    local integer i = GetHandleId(t)
    local unit u = GetSpellAbilityUnit()
    local integer lvl = GetUnitAbilityLevel(u,AbilityID)
    local real x = GetUnitX(u)
    local real y = GetUnitY(u)
    local real xx = GetSpellTargetX()
    local real yy = GetSpellTargetY()
    local real a = bj_RADTODEG*Atan2(yy-y,xx-x)
    local real aa = Atan2(y-yy,x-xx)
    local group g = CreateGroup()
    
    call wav(GetOwningPlayer(u),x+(WaveDistanceBack+(WaveDistanceBackLvl*lvl))*Cos(aa),y+(WaveDistanceBack+(WaveDistanceBackLvl*lvl))*Sin(aa),a,aa,g,Waves+(WavesLvl*lvl))
    call SaveGroupHandle(H,i,0,g)
    call SaveReal(H,i,1,WaveDistanceForward+(WaveDistanceForwardLvl*lvl))
    call SaveReal(H,i,3,WavesDamage+(lvl*WavesDamageLvl)+(GetHeroStr(u,IncludeBonuses)*DamageScaleStr)+(GetHeroAgi(u,IncludeBonuses)*DamageScaleAgi)+(GetHeroInt(u,IncludeBonuses)*DamageScaleInt))
    call SaveGroupHandle(H,i,4,CreateGroup())
    call SaveReal(H,i,5,(HeightWaveMax-HeightWaveMin)/HeightWaveFreq*0.03)
    call TimerStart(t,0.03,true,function move)
    
    if Wave+(WaveLvl*lvl) > 1 then
        set t = null
        set g = null
        set g = CreateGroup()
        set t = CreateTimer()
        set i = GetHandleId(t)
        call SaveGroupHandle(H,i,0,g)
        call SaveReal(H,i,1,WaveDistanceForward+(WaveDistanceForwardLvl*lvl))
        call SaveReal(H,i,3,WavesDamage+(lvl*WavesDamageLvl)+(GetHeroStr(u,IncludeBonuses)*DamageScaleStr)+(GetHeroAgi(u,IncludeBonuses)*DamageScaleAgi)+(GetHeroInt(u,IncludeBonuses)*DamageScaleInt))
        call SaveGroupHandle(H,i,4,CreateGroup())
        call SaveReal(H,i,7,a)
        call SaveReal(H,i,8,aa)
        call SaveReal(H,i,9,x)
        call SaveReal(H,i,10,y)
        call SaveInteger(H,i,11,lvl)
        call SaveUnitHandle(H,i,12,u)
        call TimerStart(t,WaveInterval,true,function wvs)
    endif

    set g = 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
    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
Я потратил на эту дичь примерно 8-9 часов, если бы только мой разжиженный мозг не тупил с полётом волн и другими мелкими фитчами..
В планах: доработать, чтобы волны не вылетали за границы карты (из-за чего может крашнуться игра) +
добавить модификатор урона зданиям
чтобы юнита не выталкивало в непроходимую местность
заменить переменные настроек на дефайны +
24.12.20 - обновлено
15.01.21 - обновлено
Если при запуске карты через редактор тебя выбивает в главное меню, то просто нажми Ctrl+S в редакторе, если возникнет ошибка, пожалуйста, сделай скрин и пришли мне, если ошибки не будет, то после этого карта должна запустится
`
ОЖИДАНИЕ РЕКЛАМЫ...
0
27
3 года назад
0
Нашел кучу ошибок, чуть позже выложу норм версию, так же добавлю плавное проявление/исчезновение
0
27
3 года назад
0
+ встроение своей хэш-таблицы
2
7
3 года назад
2
выглядит очень страшно
1
27
3 года назад
Отредактирован rsfghd
1
WoLLFeR, вау, вульфер)
Не ожидал после стольких лет увидеть тебя снова на хгм, видимо природа в 2021 очистилась

Помойные волны не могут выглядеть красиво, с моими то знаниями)
0
27
3 года назад
0
М, только сейчас понял как можно сделать лучше, да и нашел миллион ошибок
0
27
3 года назад
Отредактирован rsfghd
0
15.01.21
Не смог пока что реализовать то, что задумывал, просто поправил кое-какие недочёты
Загруженные файлы
0
27
3 года назад
0
собираюсь очень сильно преобразить волны, добавить больше вариативности действий, убрать сджасс, а так же сделать более дружелюбным к гуи пользователям
Чтобы оставить комментарий, пожалуйста, войдите на сайт.