• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Magic Orbs v1.4

Magic Orbs
Made by KhaosMachine

Tooltip

(Q)Magic Orbs - [Level: %d]
The hero sends five magic orbs to the target. The orbs spins around him up to 10 seconds, then start to travel to the target position. When the orbs impacts the target, deals damage to him and the units closer. When the orbs are alive, hits to the closer units.

Level 1 - The target receives 150 damage, and the closer units 90. The orbs deals 232 per second to the closer units.
Level 2 - The target receives 200 damage, and the closer units 135. The orbs deals 300 per second to the closer units.
Level 3 - The target receives 250 damage, and the closer units 180. The orbs deals 367 per second to the closer units.
Level 4 - The target receives 300 damage, and the closer units 225. The orbs deals 433 per second to the closer units.

Amount of orbs: 5
Area of effect: 325/375/425/475
Area of effect of orbs: 70/90/110/130
Duration: 10 seconds

Screenshots

JMxFj.png

7c0bq.png

ZTkDt.png


vJASS code

JASS:
scope magicOrbs initializer init

//****************************************************
//START OF THE CONFIGURATION
//IMPORTANT: IF YOU WANT PRELOAD THE SPELL WHEN YOU WANT
//TYPE THE NEXT TEXT IN JASS SCRIPT:
//call magicOrbs_PreloadSpell()
//****************************************************

    globals
        private constant integer abilityId = 'A000'//Ability id of the spell
        private constant integer unitTypeOrb = 'u000'//Unit type of the dummy
        private constant real interval = 0.03125//Interval of the spell
        private constant real orbScale = 1.5//Scale of the orb
        private constant string missileModel = "Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl"//Orb model
        private constant string specialEffect = "Abilities\\Weapons\\ZigguratMissile\\ZigguratMissile.mdl"//Explosion target model
        private constant attacktype attackType = ATTACK_TYPE_NORMAL//Attack type
        private constant damagetype damageType = DAMAGE_TYPE_NORMAL//Damage type
        private constant weapontype weaponType = WEAPON_TYPE_WHOKNOWS//Weapon type
        private constant boolean preloadSpell = TRUE
        private real angleSpeed = 2.7//Angle moved every interval
        private real normalSpeed = 3//Movement speed every interval
    endglobals

    private constant function orbsAmount takes integer level returns integer
        return 5//Total of orbs
    endfunction

    private constant function distanceBTAO takes integer level returns real
        return 150.//Distance between the target and the orbs
    endfunction

    private constant function damageTarget takes integer level returns real
        return 20. + 10. * level//Damage every orb each level
    endfunction

    private constant function damageAOE takes integer level returns real
        return 12. + 6. * level//Damage of area of effect every orb each level
    endfunction

    private constant function areaOfEffect takes integer level returns real
        return 275. + 50. * level//Area of effect of the explosions
    endfunction

    private constant function immolateDamage takes integer level returns real
        return 5. + 2. * level//Damage per interval of each orb
    endfunction

    private constant function immolateAOE takes integer level returns real
        return 50. + 20. * level//Area of effect of the 'immolate' damage
    endfunction

    private constant function duration takes integer level returns real
        return 10.//The time you have to wait to the orbs impacts the target
    endfunction
    
    private constant function filterUnits takes unit target, player owner returns boolean
        if /*
            */not IsUnitType(target, UNIT_TYPE_DEAD) /*
            */and not IsUnitType(target, UNIT_TYPE_STRUCTURE) /*
            */and not IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE) /*
            */and IsUnitEnemy(target, owner) /*
        */then
            return TRUE
        endif
        return FALSE
    endfunction

//****************************************************
//END OF THE CONFIGURATION
//****************************************************

    private struct orbsData
        unit caster
        unit orb
        unit target
        real angle
        integer level
        real time
        real distance
        effect eff
        player owner
    endstruct

    globals
        private constant timer TIMER = CreateTimer()
        private orbsData array ARRAY
        private integer TOTAL = 0
        private constant player PLAYER = Player(PLAYER_NEUTRAL_AGGRESSIVE)
    endglobals

    private function action takes nothing returns nothing
        local orbsData mo
        local integer i = 0
        local real x
        local real x1
        local real y
        local real y1
        local unit j
        loop
        exitwhen i >= TOTAL
            set mo = ARRAY[i]
            set x = GetUnitX(mo.target)
            set y = GetUnitY(mo.target)
            set x1 = GetUnitX(mo.orb)
            set y1 = GetUnitY(mo.orb)
            call GroupEnumUnitsInRange(bj_lastCreatedGroup, x1, y1, immolateAOE(mo.level), null)
            loop
                set j = FirstOfGroup(bj_lastCreatedGroup)
            exitwhen j == null
                call GroupRemoveUnit(bj_lastCreatedGroup, j)
                if filterUnits(j, mo.owner) then
                    call UnitDamageTarget(mo.caster, j, damageAOE(mo.level) * interval, true, false, attackType, damageType, weaponType)
                endif
            endloop
            set mo.angle = mo.angle + angleSpeed
            if mo.time > 0 then
                call SetUnitPosition(mo.orb, x + mo.distance * Cos(bj_DEGTORAD * mo.angle), y + mo.distance * Sin(bj_DEGTORAD * mo.angle))
            else
                set mo.distance = mo.distance - normalSpeed
                call SetUnitPosition(mo.orb, x + mo.distance * Cos(bj_DEGTORAD * mo.angle), y + mo.distance * Sin(bj_DEGTORAD * mo.angle))
            endif
            if mo.distance < 30 or IsUnitType(mo.target, UNIT_TYPE_DEAD) then
                call SetUnitExploded(mo.orb, TRUE)
                call KillUnit(mo.orb)
                call DestroyEffect(mo.eff)
                call UnitDamageTarget(mo.caster, mo.target, damageTarget(mo.level), TRUE, FALSE, attackType, damageType, weaponType)
                call DestroyEffect(AddSpecialEffect(specialEffect, x, y))
                call GroupEnumUnitsInRange(bj_lastCreatedGroup, x, y, areaOfEffect(mo.level), null)
                loop
                    set j = FirstOfGroup(bj_lastCreatedGroup)
                exitwhen j == null
                    call GroupRemoveUnit(bj_lastCreatedGroup, j)
                    if filterUnits(j, mo.owner) then
                        call UnitDamageTarget(mo.caster, j, damageAOE(mo.level), TRUE, FALSE, attackType, damageType, weaponType)
                        call DestroyEffect(AddSpecialEffect(specialEffect, GetUnitX(j), GetUnitY(j)))
                    endif
                endloop
                set ARRAY[i] = ARRAY[TOTAL - 1]
                set TOTAL = TOTAL - 1
                set mo.caster = null
                set mo.orb = null
                set mo.target = null
                set mo.eff = null
                call mo.destroy()
            endif
            set mo.time = mo.time - interval
            set i = i + 1
        endloop
        if TOTAL == 0 then
            call PauseTimer(TIMER)
        endif
    endfunction

    private function run takes nothing returns boolean
        local orbsData mo
        local unit caster
        local unit target
        local real angle
        local real x
        local real x1
        local real y
        local real y1
        local integer i
        local integer level
        local integer INTEGER
        if GetSpellAbilityId() == abilityId then
            set caster = GetTriggerUnit()
            set target = GetSpellTargetUnit()
            set level = GetUnitAbilityLevel(caster, abilityId)
            set INTEGER = orbsAmount(level)
            set x = GetUnitX(target)
            set y = GetUnitY(target)
            set i = 1
            loop
            exitwhen i > INTEGER
                set mo = orbsData.create()
                set mo.angle = (360 / INTEGER) * i
                set mo.distance = distanceBTAO(level)
                set x1 = x + mo.distance * Cos(bj_DEGTORAD * mo.angle)
                set y1 = y + mo.distance * Sin(bj_DEGTORAD * mo.angle)
                set mo.orb = CreateUnit(PLAYER, unitTypeOrb, x1, y1, mo.angle + 180)
                set mo.eff = AddSpecialEffectTarget(missileModel, mo.orb, "origin")
                set mo.caster = caster
                set mo.target = target
                set mo.level = level
                set mo.time = duration(level)
                set mo.owner = GetTriggerPlayer()
                if TOTAL == 0 then
                    call TimerStart(TIMER, interval, TRUE, function action)
                endif
                set TOTAL = TOTAL + 1
                set ARRAY[TOTAL - 1] = mo
                set i = i + 1
            endloop
        endif
        set caster = null
        set target = null
        return FALSE
    endfunction

    public function PreloadSpell takes nothing returns nothing
        local unit preloader = CreateUnit(PLAYER, unitTypeOrb, 0, 0, 0)
        call UnitAddAbility(preloader, abilityId)
        call RemoveUnit(preloader)
        call Preload(specialEffect)
        call Preload(missileModel)
        set preloader = null
    endfunction

    private function init 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 run))
        if preloadSpell then
            call PreloadSpell()
        endif
        set t = null
    endfunction

endscope

Credits and some info

Credits:

I made this spell because I love make spells, haha :p. This is my second vJASS spell, sorry for the errors or bugs if it have any!

Updates

Last update:
  • Some fixes, last version I think



Keywords:
magic orb, vjass spell, jass spell, gui spell, khaosmachine, love spells, nice spell, for my map, rpg, blizzlike
Contents

Magic Orbs (Map)

Reviews
00:07, 17th Jul 2012 Magtheridon96: Okay, well done. The code is incredibly decent. When the target unit dies, all orbs around him should just die out too. The filters should be configurable. To achieve this, you need to write functions...

Moderator

M

Moderator

00:07, 17th Jul 2012
Magtheridon96: Okay, well done.
The code is incredibly decent.

  • When the target unit dies, all orbs around him should just die out too.
  • The filters should be configurable. To achieve this, you need to
    write functions right under the globals that take the caster, the
    target and maybe the player, and you would decide whether the
    target is valid or not.
  • In the init function, instead of bj_lastCreatedUnit, you could use
    a local unit variable. If you don't want to use a local, then what you
    should do is /not/ null bj_lastCreatedUnit because it's a global, so
    you really don't need to.
  • Before you destroy the struct instances, you should null the
    handles inside it:
    JASS:
    set mo.orb = null
    set mo.caster = null
    set mo.target = null
    set mo.eff = null

edit
Approved.


  • TRUE -> true
  • FALSE -> false
  • You forgot to null the local unit inside the preload function :c
  • You forgot to null the effect .eff in the stuct :c
  • Instead of SetUnitPosition, use SetUnitX and SetUnitY (They're a lot faster and better because they ignore collision)
  • It would probably be better to cache the owner of the caster into a struct member.

Also, I love you.
 
Level 8
Joined
Dec 30, 2011
Messages
134
The version is different of your warcraft patch!
try th lates! ;) also ples show th version patch!

Why can not run your map???

When I try to start it,just will not go and throw me out of the game

You can't open it because you need the Jass New Gen Pack editor for the world editor!

Can download here:
Jass New Gen Pack

NOTE: You have to add the folder named 'jassnewgenpack5d' into the ANTIVIRUS EXCEPTIONS! Then open the map, save it (wait to the jasshelper runs) and inmediatly TEST IT!
 
Level 10
Joined
Aug 21, 2010
Messages
316
You can't open it because you need the Jass New Gen Pack editor for the world editor!

Can download here:
Jass New Gen Pack

NOTE: You have to add the folder named 'jassnewgenpack5d' into the ANTIVIRUS EXCEPTIONS! Then open the map, save it (wait to the jasshelper runs) and inmediatly TEST IT!

I did not even try to open it with an editor.The game will not launch map.
Otherwise I have the last patch

This map "Fan Of Toxic Knives" work fine.
Well I do not understand what the problem!
 
You can't open it because you need the Jass New Gen Pack editor for the world editor!

Can download here:
Jass New Gen Pack

NOTE: You have to add the folder named 'jassnewgenpack5d' into the ANTIVIRUS EXCEPTIONS! Then open the map, save it (wait to the jasshelper runs) and inmediatly TEST IT!

No point in explaining, google answers all.
 
Top