• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

C:\fakepath\SE

Level 14
Joined
Oct 19, 2014
Messages
187
I need some advise please.
because I waste me time on making this, because my keyboard is broken, and I use Ease Center, Keyboard on screen , and it is so tiered.

Screenshot:
241353-albums8144-picture97912.png


Description:
241353-albums8144-picture97911.png

JASS:
library SpellEnergy /* v1.0
****************************************************************************************
*
*  */ uses /*
*
*       */ UnitTimed /*
*       */ Init      /*
*
****************************************************************************************
*
*    Spell Energy
*        by Silver Dust (usd99)
*
*
*    Requirements
*        Init
*        UnitTimed
*        Any Unit Indexer
*
*
*    Credits
*        Owner of init
*
*
****************************************************************************************/

    globals
        //Determine the Ability id of Spell Energy
        private constant    integer   SE_AbilityId       = 'A001'
        //Determine the Unit id of Fire ball
        private constant    integer   SE_FireDummyId     = 'h000'
        //Determine the Unit id of Water ball
        private constant    integer   SE_WaterDummyId    = 'h001'
        //Determine the Unit id of Electrict ball
        private constant    integer   SE_ElectrictDummyId= 'h002'
        //Determine the limit number of balls
        private constant    integer   SE_SpawnLimit      = 8
        //Determine the addtional number for spawnlimit in every levels of ability
        private constant    integer   SE_LvSpawnAdd      = 2
        //Determine the speed rotation of balls
        private constant    real      SE_SpeedAngle      = 4
        //Determine the speed of ball when going back to caster
        private constant    real      SE_Speed2Caster    = 25
        //Determine the speed of ball going to target position
        private constant    real      SE_Speed2Target    = 35
        //Determine the distance of ball to caster
        private constant    real      SE_MoveDist2Caster = 150
        //Determine the end distance to target
        private constant    real      SE_EndDist2Target  = SE_Speed2Target*2
        //Determine the flying height of dummy at all time
        private constant    real      SE_DummyZ          = 50
        //Determine the low bound damage of electrict
        private constant    real      SE_ElectDamageMin  = 35
        //Determine the high bound damage of electrict
        private constant    real      SE_ElectDamageMax  = 100
        //Determine the low bound damage of fire
        private constant    real      SE_FireDamageMin   = 25
        //Determine the high bound damage of fire
        private constant    real      SE_FireDamageMax   = 125
        //Determine the low bound damage of water
        private constant    real      SE_WaterDamageMin  = 20
        //Determine the high bound damage of water
        private constant    real      SE_WaterDamageMax  = 95
        //Determine the damage of burn per interval
        private constant    real      SE_BurnDmgPerInter = 15
        //Determine the interval of burn
        private constant    real      SE_BurnInterval    = 1
        //Determine the desire duration of burn
        private constant    real      SE_BurnDuration    = 5
        //Determine the damage of paralize per interval
        private constant    real      SE_ParDmgPerInter = 0
        //Determine the interval of paralize
        private constant    real      SE_ParInterval    = 0.25
        //Determine the desire duration of paralize
        private constant    real      SE_ParDuration    = 5
        //Determine the damage type of lightning ball
        private constant    damagetype SE_LightningDType = DAMAGE_TYPE_LIGHTNING
        //Determine the damage type of fire ball
        private constant    damagetype SE_FireDType      = DAMAGE_TYPE_FIRE
        //Determine the damage type of water ball
        private constant    damagetype SE_WaterDType     = DAMAGE_TYPE_MAGIC
        //Determine the attack type of all damages
        private constant    attacktype SE_AllAType       = ATTACK_TYPE_NORMAL
        //Determine the order of paralize
        private constant    string    SE_ParOrder        = "stop"
        //Determine the attachment of all fx
        private constant    string    SE_FxAttach        = "origin"
        //Determine the fx of burn
        private constant    string    SE_FxBurn          = "Abilities\\Spells\\Human\\FlameStrike\\FlameStrikeEmbers.mdl"
        //Determine the fx of paralize
        private constant    string    SE_FxPar           = "Abilities\\Spells\\Orc\\LightningShield\\LightningShieldBuff.mdl"
        //End of Configure
        private integer array SE_SpawnId
        private integer array SE_SpawnCount
        private integer array SE_BIndexThis
        private integer array SE_PIndexThis
        private integer array SE_IndexThis
        private integer SE_IndexBurn = 0
        private integer SE_IndexPar = 0
        private integer SE_IndexDummy = 0
        private unit SE_TempUnit = null
        private timer SE_Timer = CreateTimer()
        private timer SE_BurnTimer = CreateTimer()
        private timer SE_ParTimer = CreateTimer()
    endglobals
    
    struct SpellEnergy
    
        unit d
        unit do
        unit dt
        real da
        
        unit bu
        unit bc
        real bd
        real bdmg
        real bint
        real btr
        effect bfx
        
        unit pu
        unit pc
        real pd
        real pdmg
        real pint
        real ptr
        
        private static method onParPer takes nothing returns nothing
            local integer i = 1
            local thistype this
            
            loop
                exitwhen i > SE_IndexPar
                set this = SE_PIndexThis[i]
                if pd > 0 and not IsUnitType(pu,UNIT_TYPE_DEAD) then
                    if pint > ptr then
                        set ptr = ptr + 0.03125
                    else
                        call DestroyEffect(AddSpecialEffectTarget(SE_FxPar,pu,SE_FxAttach))
                        call UnitDamageTarget(pc,pu,pdmg,false,false,SE_AllAType,SE_LightningDType,null)
                        call IssueImmediateOrder( pu,SE_ParOrder  )
                        set ptr = 0
                    endif
                    set pd = pd - 0.03125
                else
                    set SE_PIndexThis[i] = SE_PIndexThis[SE_IndexPar]
                    set SE_IndexPar = SE_IndexPar - 1
                    set i = i - 1
                    call destroy()
                    if SE_IndexPar == 0 then
                        call PauseTimer(SE_ParTimer)
                    endif
                endif
                set i = i + 1
            endloop
        endmethod
        
        private static method onParCast takes unit u, unit c, real d, real dmg, real interval returns nothing
            local thistype this = allocate()
            local real a
            set SE_IndexPar = SE_IndexPar + 1
            set SE_PIndexThis[SE_IndexPar] = this
            set pu = u
            set pc = c
            set pd = d
            set pdmg = dmg
            set pint = interval
            set ptr = 0
            if SE_IndexPar == 1 then
                call TimerStart(SE_ParTimer,0.03125,true,function thistype.onParPer)
            endif
        endmethod
        
        private static method onBurnPer takes nothing returns nothing
            local integer i = 1
            local thistype this
            
            loop
                exitwhen i > SE_IndexBurn
                set this = SE_BIndexThis[i]
                if bd > 0 and not IsUnitType(bu,UNIT_TYPE_DEAD) then
                    if bint > btr then
                        set btr = btr + 0.03125
                    else
                        call UnitDamageTarget(bc,bu,bdmg,false,false,SE_AllAType,SE_FireDType,null)
                        set btr = 0
                    endif
                    set bd = bd - 0.03125
                else
                    call DestroyEffect(bfx)
                    set SE_BIndexThis[i] = SE_BIndexThis[SE_IndexBurn]
                    set SE_IndexBurn = SE_IndexBurn - 1
                    set i = i - 1
                    call destroy()
                    if SE_IndexBurn == 0 then
                        call PauseTimer(SE_BurnTimer)
                    endif
                endif
                set i = i + 1
            endloop
        endmethod
        
        private static method onBurnCast takes unit u, unit c, real d, real dmg, real interval returns nothing
            local thistype this = allocate()
            local real a
            set SE_IndexBurn = SE_IndexBurn + 1
            set SE_BIndexThis[SE_IndexBurn] = this
            set bu = u
            set bc = c
            set bd = d
            set bdmg = dmg
            set bint = interval
            set btr = 0
            set bfx = AddSpecialEffectTarget(SE_FxBurn,u,SE_FxAttach)
            if SE_IndexBurn == 1 then
                call TimerStart(SE_BurnTimer,0.03125,true,function thistype.onBurnPer)
            endif
        endmethod
        
        private static method onPeriodic takes nothing returns nothing
        
            local integer i = onInit
            local integer i1
            local thistype this
            local real x
            local real y
            local real x1
            local real y1
            local real x2
            local real y2
            local real dist
            local real dx
            local real dy
            local real a
            
            loop
                exitwhen i > SE_IndexDummy
                set this = SE_IndexThis[i]
                
                set x = GetUnitX(do)
                set y = GetUnitY(do)
                set x1 = GetUnitX(d)
                set y1 = GetUnitY(d)
                
                if not IsUnitType(d,UNIT_TYPE_DEAD) and dt == null and not IsUnitType(do,UNIT_TYPE_DEAD) and not (do == null) and (GetRectMinX(bj_mapInitialPlayableArea) <= x) and (x <= GetRectMaxX(bj_mapInitialPlayableArea)) and (GetRectMinY(bj_mapInitialPlayableArea) <= y) and (y <= GetRectMaxY(bj_mapInitialPlayableArea))then
                    set dx = x - x1
                    set dy = y - y1
                    set dist  = SquareRoot(dx * dx + dy * dy)
                    if dist > SE_MoveDist2Caster+SE_Speed2Caster then
                        set a = bj_RADTODEG * Atan2(y - y1, x - x1)
                        set da = a+180
                        
                        call SetUnitFacing(d,a)
                        call SetUnitX(d,x1+SE_Speed2Caster*Cos(a*bj_DEGTORAD))
                        call SetUnitY(d,y1+SE_Speed2Caster*Sin(a*bj_DEGTORAD))
                    else
                        if da >= 360 then
                            set da = 1
                        else
                            set da = da + SE_SpeedAngle
                        endif
                        
                        call SetUnitFacing(d,da+90)
                        call SetUnitX(d,x+SE_MoveDist2Caster*Cos(da*bj_DEGTORAD))
                        call SetUnitY(d,y+SE_MoveDist2Caster*Sin(da*bj_DEGTORAD))
                    endif
                    call SetUnitFlyHeight(d,SE_DummyZ,0)
                else
                    if dt != null and not IsUnitType(dt,UNIT_TYPE_DEAD) and not IsUnitType(d,UNIT_TYPE_DEAD) then
                        set x2 = GetUnitX(dt)
                        set y2 = GetUnitY(dt)
                        set dx = x2 - x1
                        set dy = y2 - y1
                        set dist  = SquareRoot(dx * dx + dy * dy)
                        if dist > SE_EndDist2Target+SE_Speed2Caster then
                            set a = bj_RADTODEG * Atan2(y2 - y1, x2 - x1)
                            set da = a+180
                        
                            call SetUnitFacing(d,a)
                            call SetUnitX(d,x1+SE_Speed2Target*Cos(a*bj_DEGTORAD))
                            call SetUnitY(d,y1+SE_Speed2Target*Sin(a*bj_DEGTORAD))
                            call SetUnitFlyHeight(d,SE_DummyZ,0)
                        else
                            call KillUnit(d)
                            call UnitTimedRegister(d,1)
                            set SE_SpawnCount[GetUnitUserData(do)] = SE_SpawnCount[GetUnitUserData(do)] - 1
                            if GetUnitTypeId(d) == SE_SpawnId[1] then
                                call onBurnCast(dt,do,SE_BurnDuration,SE_BurnDmgPerInter,SE_BurnInterval)
                                call UnitDamageTarget(do,dt,GetRandomReal(SE_FireDamageMin,SE_FireDamageMax),false,false,SE_AllAType,SE_FireDType,null)
                            elseif GetUnitTypeId(d) == SE_SpawnId[2] then
                                call UnitDamageTarget(do,dt,GetRandomReal(SE_WaterDamageMin,SE_WaterDamageMax),false,false,SE_AllAType,SE_WaterDType,null)
                            elseif GetUnitTypeId(d) == SE_SpawnId[3] then
                                call onParCast(dt,do,SE_ParDuration,SE_ParDmgPerInter,SE_ParInterval)
                                call UnitDamageTarget(do,dt,GetRandomReal(SE_ElectDamageMin,SE_ElectDamageMax),false,false,SE_AllAType,SE_LightningDType,null)
                            endif
                            
                            if SE_SpawnCount[GetUnitUserData(do)] > 0 and IsUnitType(dt,UNIT_TYPE_DEAD) then
                                set SE_TempUnit = do
                                set i1 = onInit
                                loop
                                    exitwhen i1 > SE_IndexDummy
                                    set this = SE_IndexThis[i1]
                                    if do == SE_TempUnit then
                                        set dt = null
                                    endif
                                    set i1 = i1 + onInit
                                endloop
                            endif
                        endif
                    else
                        set SE_IndexThis[i] = SE_IndexThis[SE_IndexDummy]
                        set SE_IndexDummy = SE_IndexDummy - onInit
                        set i = i - onInit
                        call destroy()
                        if SE_IndexDummy == 0 then
                            call PauseTimer(SE_Timer)
                        endif
                    endif
                endif
                set i = i + onInit
            endloop
        endmethod
        
        private static method onCast takes nothing returns boolean
            
            local thistype this
            local integer i
            local unit u = GetTriggerUnit()
            local integer ud = GetUnitUserData(u)
            local integer lvl = GetUnitAbilityLevel(u,SE_AbilityId)
            
            if GetSpellAbilityId() != SE_AbilityId then
                if GetUnitAbilityLevel(u,SE_AbilityId) > 0 and SE_SpawnLimit + (SE_LvSpawnAdd * lvl) > SE_SpawnCount[ud] then
                    set this = allocate()
                    set SE_IndexDummy = SE_IndexDummy + onInit
                    set SE_IndexThis[SE_IndexDummy] = this
                    
                    set do = u
                    set da = GetRandomReal(1,359)
                    set dt = null
                    set UI_Enable = true
                    set d = CreateUnit(Player(15),SE_SpawnId[GetRandomInt(1,3)],GetUnitX(u),GetUnitY(u),da)
                    set UI_Enable = false
                    call UnitAddAbility(d,'Avul')
                    call UnitAddAbility(d,'Arav')
                    set SE_SpawnCount[ud] = SE_SpawnCount[ud] + onInit
                    
                    if SE_IndexDummy == onInit then
                        call TimerStart(SE_Timer,0.03,true,function thistype.onPeriodic)
                    endif
                else
                    return false
                endif
            else
                if SE_SpawnCount[ud] > 0 then
                    set i = onInit
                    loop
                        exitwhen i > SE_IndexDummy
                        set this = SE_IndexThis[i]
                        if do == u then
                            set dt = GetSpellTargetUnit()
                        endif
                        set i = i + onInit
                    endloop
                endif
                
            endif
            
            set u = null
            set ud = 0
            set lvl = 0
            
            return false
        endmethod
        private static method onInit takes nothing returns nothing
            
            local trigger trig = CreateTrigger()
            
            call TriggerRegisterAnyUnitEventBJ(trig,EVENT_PLAYER_UNIT_SPELL_EFFECT)
            call TriggerAddAction(trig,function thistype.onCast)
            
            set SE_SpawnId[1] = SE_FireDummyId
            set SE_SpawnId[2] = SE_WaterDummyId
            set SE_SpawnId[3] = SE_ElectrictDummyId
            
        endmethod
        
        implement Init
    endstruct
endlibrary

Attachments

  • SE v1.0.w3x
    32 KB · Views: 17
Last edited:
Top