1. Are you planning to upload your awesome spell or system to Hive? Please review the rules here.
    Dismiss Notice
  2. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  3. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  4. The Lich King demands your service! We've reached the 19th edition of the Icon Contest. Come along and make some chilling servants for the one true king.
    Dismiss Notice
  5. The 4th SFX Contest has started. Be sure to participate and have a fun factor in it.
    Dismiss Notice
  6. The poll for the 21st Terraining Contest is LIVE. Be sure to check out the entries and vote for one.
    Dismiss Notice
  7. The results are out! Check them out.
    Dismiss Notice
  8. Don’t forget to sign up for the Hive Cup. There’s a 555 EUR prize pool. Sign up now!
    Dismiss Notice
  9. The Hive Workshop Cup contest results have been announced! See the maps that'll be featured in the Hive Workshop Cup tournament!
    Dismiss Notice
  10. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

Reflections of Light [Paladon] v.1.1.2e

Submitted by Paladon
This bundle is marked as approved. It works and satisfies the submission rules.
-=Reflections of Light=-
by (c) Paladon

The spell "Reflections of Light" is coded in vJass.
It needs the JassNewGenPack in order to be modified/used properly.
You can get the JNGP here: Click
Description:
Creates a shield of holy energy around the caster.
The energy forms orbs flying in an orbital shape around the hero.
Whenever the hero receives damage, an orb is launched to the enemy
countering the damage dealt. The shield lasts 30 seconds.
Level 1 - 3 orbs, each deals 120% of the initial damage.
Level 2 - 6 orbs, each deals 210% of the initial damage.
Level 3 - 9 orbs, each deals 300% of the initial damage.

Import
To import this spell into your very own map, you need to work with the JNGP named above.
For this spell, you need the "Reflections of Light" trigger (below the Readme)
as well as the DUMMY.mdx out of the Import Editor and the Dummy unit out of the Object Editor.
Furthermore, you need the spell "Reflections of Light" which is located in the Object Editor as well.

Import and copy all these things into your map and adjust the settings in the header of the
"Reflections of Light" trigger to your own needs.

Thankswishing
I`d like to thank Eccho and Hanky for their quick feedback and help concerning things i oversaw.
Thanks also to Dr Super Good, he helped me solving problems concerning event removal.
I additionally thank the clans AuKn@Northrend and NgO@Northrend
as well as all the scripters and coders i`ve worked with in my previous times.
Naming them all here would be just a hilarious long list. But i thought of you all.

Other stuff
The usual ownership conditions apply.
~Paladon


Changelog

v.0.9.9b
- inofficial release ( 2 versions)

v.1.0.5a
- official release

v.1.0.8a
- added changelog
- replaced a real recylce with a better one
- added chooseable minimal damage amount to trigger it
- launched orbs become removed if their target dies before reaching it

v.1.1.2b
- saved space by the removal of the trigger actions
- added dots behind reals to prevent desyncs
- replaced the damage detection update part with a simple condition
- removed one unitgroup by a struct bypass
- the unit launches now just one orbital at a single unit upon strike, no matter the number of recasts. Recasting the spell on the unit now adds the orbitals to the unit without launching more than one.

v.1.1.2c
- got rid of all trigger actions

v.1.1.2d
- fixed a problem with degrees and radians

v.1.1.2e
- fixed a problem concerning triggering


Code

Code (vJASS):

scope ReflectionOfLight initializer SetEvent
    globals
        //! general settings
        private constant integer SpellID       = 'A000' // Spell's rawcode
        private constant integer DummyID       = 'n000' // Dummy's rawcode
        private constant real    Timer         = 0.01   // Interval of the timer
       
        private constant integer InitOrbAmount = 3  // Amount of orbs at level 1
        private constant integer IncrOrbAmount = 3  // Amount of orbs added with every further level
        private constant real    InitTime      = 30. // How long the effect lasts on level 1
        private constant real    AddTime       = 0.  // Amount of time added per level
       
        private constant string OrbModel       = "Abilities\\Spells\\Other\\HealingSpray\\HealBottleMissile.mdl" // Model of the orbs
        private constant string OrbCreation    = "Abilities\\Spells\\Other\\HealingSpray\\HealBottleMissile.mdl" // Model of the "death" animation displayed upon creation of the orbs
        private constant string OrbImpact      = "Abilities\\Spells\\Other\\HealingSpray\\HealBottleMissile.mdl" // Model of the "death" animation displayed upon impact on enemied units
        private constant string DummyAttach    = "chest" // Attachment point oof the effects on the "Dummy" model as well as the attachment point used on the enemy
       
        private constant real OrbitalSpeedMin  = 2.05 // Defines the minimal orbital speed
        private constant real OrbitalSpeedMax  = 2.55 // Defines the maximal orbital speed
       
        private constant real OrbitalAngSpMin  = -0.55 // Defines the minimal speed of the spin of the orbital movement
        private constant real OrbitalAngSpMax  = 0.55  // Defines the maximal speed of the spin of the orbital movement
       
        private constant real OrbitalSizeMin   = 110.   // Defines the minimal size of the orbital movement of a single orb
        private constant real OrbitalSizeMax   = 150.   // Defines the maximal size of the orbital movement of a single orb
       
        private constant real OrbitalHeightMin = 45.    // Defines partially the height of the orbital (minimal).
        private constant real OrbitalHeightMax = 60.    // Defines partially the height of the orbital (maximal).
         //!I recommend playing around with this value for ground units to find something fitting. For air units, i recommend simply "0".
       
        private constant real MinDamageCounter = 5. // Returns the minimal damage necessary to release a countering orb
       
        private constant real ReleasedSpeed    = 4.5   // The flying speed of a released orb.
        private constant real PercCounterInit  = 120.   // The percentage of damage returned at level 1
        private constant real PercCounterAdd   = 90.   // The percentage of damage to return added for every further level
       
        private constant attacktype ATT        = ATTACK_TYPE_NORMAL   // The attacktype of the damage dealt
        private constant damagetype DGT        = DAMAGE_TYPE_NORMAL   // The damagetype of the damage dealt
        private constant weapontype WPT        = WEAPON_TYPE_WHOKNOWS // The weapontype of the damage dealt
       
//!*******************************END OF THE SETTINGS*************************!\\
//**Do not modify anything below this line unless you know what you are doing**\\
//!***************************************************************************!\\
        private real array R
        private trigger DmgSys = CreateTrigger()
        private group DSys = CreateGroup()
    endglobals

    private struct S
        private unit    h
        private unit    o
        private unit    t
        private integer l
        private integer s
       
        private real d1
        private real d2
        private real a1
        private real t1
        private real t2
       
        private real OSp
        private real OAS
        private real OSi
        private real OHe
        private real OEx
       
        private effect fx
       
        private static S array indx
        private static integer counter = 0
        private static timer   time    = CreateTimer()
           
            static method ChangeStruct takes nothing returns boolean    
                //! This function interrupts the struct and adjusts the orb's movement type.
                local S d
                local integer i = 0
                local integer ii = 0
                local unit u = GetTriggerUnit()
                set R[0] = GetEventDamage()
                if R[0] >= MinDamageCounter then
                    loop
                        exitwhen i >= S.counter
                        set d = S.indx[i]
                        if d.h == u and d.s == 1 then
                            //! An orb flying in an orbital shape around the attacked hero is detected here.
                            //! d.s = 1 means orbital movement
                            //! d.s = 2 means movement to a target
                            set d.s  = 2
                            set d.t  = GetEventDamageSource()
                            set d.d2 = R[0]*((PercCounterInit+(PercCounterAdd*d.l))/100)
                            set R[0] = 0
                            set i = S.counter
                        endif  
                        set i = i + 1
                    endloop
                endif
                set u = null
                return true
            endmethod
           
            static method Execution takes nothing returns nothing
                local S d
                local integer i = 0
                local unit u
                loop
                    exitwhen i >= S.counter
                    set d = S.indx[i]
                   
                    if d.s == 0 then
                        //! Remove & Recycle
                        call DestroyEffect(d.fx)
                        call RemoveUnit(d.o)
                        set  d.h      = null
                        set  d.o      = null
                        set  d.t      = null
                        call d.destroy()                      
                        set  S.counter = S.counter - 1
                        set  S.indx[i] = d.indx[S.counter]                      
                        set  i = i - 1  

                    elseif d.s == 1 then
                        //! The formula for the orbital movement (by me, i've been asked this already before the official release)
                        set d.t1 = d.t1 + Timer
                        set d.a1 = d.a1 + d.OAS
                        set d.d1 = d.d1 + d.OSp
                        set R[0] = (d.d1/d.OEx)*bj_DEGTORAD
                        set R[1] = d.OSi*Sin(R[0])
                        set R[2] = d.a1*bj_DEGTORAD
                        call SetUnitX(d.o,GetUnitX(d.h)+R[1]*Cos(R[2]))
                        call SetUnitY(d.o,GetUnitY(d.h)+R[1]*Sin(R[2]))
                        call SetUnitFlyHeight(d.o,(d.OSi-d.OHe)*Cos(R[0])+d.OHe+GetUnitFlyHeight(d.h),0)
                        set R[2] = 0
                        //! Since the orbs move with a circular movement, we can reset the angle.
                        if d.a1 >= 360 then
                            set d.a1 = d.a1 - 360
                        endif
                       
                        if d.t1 >= d.t2 or GetUnitState(d.h,UNIT_STATE_LIFE) == 0 then
                            set d.s = 0
                        endif
                    elseif d.s == 2 then
                        //! Launch and move the missile
                       
                        //! X/Y Movement
                        set R[0] = GetUnitX(d.t)
                        set R[1] = GetUnitY(d.t)
                        set R[2] = GetUnitX(d.o)
                        set R[3] = GetUnitY(d.o)
                        set R[4] = Atan2(R[1]-R[3],R[0]-R[2])  
                        call SetUnitX(d.o,R[2] + ReleasedSpeed * Cos(R[4]))
                        call SetUnitY(d.o,R[3] + ReleasedSpeed * Sin(R[4]))
                       
                        //! Z Movement
                        set R[0] = R[2] - R[0]
                        set R[1] = R[3] - R[1]
                        set R[2] = SquareRoot(R[0]*R[0]+R[1]*R[1])
                        set R[0] = GetUnitFlyHeight(d.t)
                        set R[1] = GetUnitFlyHeight(d.o)
                        set R[0] = R[0]-R[1]
                        set R[0] = R[0]/(R[2]/ReleasedSpeed)
                        call SetUnitFlyHeight(d.o,R[1]+R[0],0)

                        //! Exit
                        if R[2] <= ReleasedSpeed then
                            set d.s = 0
                            call DestroyEffect(AddSpecialEffectTarget(OrbImpact,d.t,DummyAttach))
                            call UnitDamageTarget (d.h,d.t,d.d2,true,false,ATT,DGT,WPT)
                        elseif GetUnitState(d.t,UNIT_STATE_LIFE) == 0 then
                            set d.s = 0
                        endif
                    endif
                    set i = i + 1
                endloop
                set u = null
                set i = 0
                if S.counter == 0 then
                    call PauseTimer(S.time)
                endif
            endmethod
           
            static method SetStruct takes unit h, real a1, real a2, real t2, integer l returns nothing
                //! This method mainly inits the orbital movement data and determines the movement shape
                local S d = S.allocate()
                set d.h   = h
                set d.s   = 1
                set d.l   = l
                set d.d1  = 0
                set d.a1  = (360/a1)*a2
                set d.t1  = 0
                set d.t2  = t2
                set d.OSp = GetRandomReal(OrbitalSpeedMin,OrbitalSpeedMax)
                set d.OSi = GetRandomReal(OrbitalSizeMin,OrbitalSizeMax)
                set d.OAS = GetRandomReal(OrbitalAngSpMin,OrbitalAngSpMax)*bj_DEGTORAD
                set d.OHe = GetRandomReal(OrbitalHeightMin,OrbitalHeightMax)
                set d.OEx = d.OSi/90
                set   d.o = CreateUnit(GetOwningPlayer(h),DummyID,GetUnitX(h),GetUnitY(h),0)
                call UnitAddAbility(d.o,'Arav')
                call UnitRemoveAbility(d.o,'Arav')
                call DestroyEffect(AddSpecialEffectTarget(OrbCreation,d.o,DummyAttach))
                set d.fx = AddSpecialEffectTarget(OrbModel,d.o,DummyAttach)
                if S.counter   == 0 then
                    call TimerStart(S.time,Timer,true,function S.Execution)
                endif
                set S.indx[S.counter] = d
                set S.counter = S.counter + 1
            endmethod
           
            static method Create takes nothing returns nothing
                //! The hero is added to the damage detection
                local unit u = GetTriggerUnit()
                if not IsUnitInGroup(u,DSys) then
                    call GroupAddUnit(DSys,u)
                    call TriggerRegisterUnitEvent(DmgSys,u,EVENT_UNIT_DAMAGED)
                endif
                //! Create the orbs
                set   R[0]   = 0
                set   R[2]   = GetUnitAbilityLevel(u,SpellID)-1
                set   R[1]   = InitOrbAmount+(IncrOrbAmount*R[2])
                loop
                    exitwhen R[0] == R[1]
                    call S.SetStruct(u,R[1],R[0],InitTime+(AddTime*R[2]),R2I(R[2]))
                    set R[0] = R[0] + 1
                endloop
            endmethod
    endstruct
   
    private function condition takes nothing returns boolean
        if GetSpellAbilityId() == SpellID then
            call S.Create()
        endif
        return true
    endfunction
   
    private function SetEvent takes nothing returns nothing
        //! Trigger init
        local trigger t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(t, Condition(function condition))
        call TriggerAddCondition(DmgSys,Filter(function S.ChangeStruct))
        //! Preloading effects
        call Preload(OrbCreation)
        call Preload(OrbImpact)
        call Preload(OrbModel)
        call PreloadStart()
    endfunction
endscope



Keywords:
Light, Holy, Magic, Shield, Absorb, Counter, Hero, Might, Power, Unleash, launch, Orbit, Missile, Orb, Movement, Formula, Paladin, Church, Priest, Dam
Contents

Reflections of Light [Paladon] (Map)

Reviews
Moderator
12:02, 12th Sep 2009 Hanky: Good job Paladon. In my opinion the spell looks really amazing and the coding is just nice. And also the use of special effects is nicely done. So I have no reason why I shouldn't approve this spell. I just can...
  1. Paladon

    Paladon

    Joined:
    Dec 6, 2007
    Messages:
    2,083
    Resources:
    42
    Icons:
    28
    Packs:
    2
    Spells:
    12
    Resources:
    42
    Meh, it was approved months ago.
    I just made an update.
     
  2. Alagremm

    Alagremm

    Joined:
    Nov 17, 2008
    Messages:
    4,436
    Resources:
    1
    Models:
    1
    Resources:
    1
    lol That was unexpected
     
  3. incinerate11

    incinerate11

    Joined:
    Oct 5, 2009
    Messages:
    31
    Resources:
    0
    Resources:
    0
    this is pretty epic, + rep dude I NEED MORE SPELLS!!! :p
     
  4. Raziel_br

    Raziel_br

    Joined:
    Oct 13, 2008
    Messages:
    554
    Resources:
    0
    Resources:
    0
    I'm using the jass pack, I imported the dummy.mdx, I copy and paste on my map the abilit and the dummy unit, I copy and paste on my map the trigger..

    wats wrong?
    don't works...
    =\
     
  5. BeTaGod-

    BeTaGod-

    Joined:
    May 13, 2010
    Messages:
    145
    Resources:
    3
    Icons:
    2
    Maps:
    1
    Resources:
    3
    Awesome spell, 5/5 + rep

    I got a problem, though. The spell effect (i mean the orbs) are not appearing ingame, but the effect on impact with the enemy is. What am i doing wrong? I noticed this also happend with a couple of other imported vJASS spells.. I smell incompatibility issues? Cheers!


    EDIT: Don't even bother, i worked it out.
     
    Last edited: Feb 14, 2012
  6. Ricola3D

    Ricola3D

    Joined:
    Feb 27, 2019
    Messages:
    224
    Resources:
    1
    Maps:
    1
    Resources:
    1
    Hello,

    I tried with version 1.30.4 and 1.31, I cannot launch your test map. In game, when you select the map from your maps folder it shows a pop-up that says it couldn't read the map file. From editor, when you launch the map an empty error pop-up shows up.

    Is it only compatible with older versions ? :)
     
  7. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,051
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Make sure your JassHelper is enabled when saving his map. I don't think it should cause an error otherwise. Also, that your map script is compiled with JASS and not Lua.