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. Don’t forget to sign up for the Hive Cup. There’s a 555 EUR prize pool. Sign up now!
    Dismiss Notice
  5. The Hive Workshop Cup contest results have been announced! See the maps that'll be featured in the Hive Workshop Cup tournament!
    Dismiss Notice
  6. Units have been turned into heroes in our latest Icon Contest! Vote for the best icon set at the Icon Contest #18 Poll!
    Dismiss Notice
  7. The poll for Hive's 12th Concept Art Contest is up! Go cast your vote for your favourite genie!
    Dismiss Notice
  8. The raddest synthwave tracks were chosen - Check out our Music Contest #12 - Results and congratulate the winners!
    Dismiss Notice
  9. 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.

Charged Lightning Shield v1.1

Submitted by Teelo
This bundle is marked as substandard. It may contain bugs, not perform optimally or otherwise be in violation of the submission rules.
Charged Lightning Shield is based off the Shaman - Lightning Shield spell.
This spell is self-cast, and has a limited number of charges. Instead of damaging all units around, it is like thorns - it damages units that attack it (even ranged).

The number of charges, damage amount, and damage type can be changed in the global constants section of the code.

Charges can optionally stack (default is unstackable) when lightning shield is recast.

This was made to fill a request.
Requester didn't specify whether he only wants melee attacks to take the damage.

Requires vJASS.

Keywords:
charged, lightning shield
Contents

Just another Warcraft III map (Map)

Reviews
Moderator
12th Dec 2015 IcemanBo: Too long time as NeedsFix. Rejected. 16:37, 18th Mar 2010 TriggerHappy: Do not create your own damage detection, use an existing (approved) one.
  1. 12th Dec 2015
    IcemanBo: Too long time as NeedsFix. Rejected.

    16:37, 18th Mar 2010
    TriggerHappy:

    Do not create your own damage detection, use an existing (approved) one.
     
  2. Catch_ya

    Catch_ya

    Joined:
    May 21, 2009
    Messages:
    982
    Resources:
    1
    Spells:
    1
    Resources:
    1
    Can you please post code? Sorry, I'm too lazy to download.
     
  3. GregerTheGreat

    GregerTheGreat

    Joined:
    Sep 21, 2008
    Messages:
    42
    Resources:
    0
    Resources:
    0
    Here it is.

    Code (Text):

    //TESH.scrollpos=0
    //TESH.alwaysfold=0
    library ChargedLightningShield initializer init

        globals
            // Change this to the number of charges you want the lightning shield to have
            private constant integer MAX_CHARGES = 3
            // Change this to the base damage of the orbs
            private constant integer ORB_DAMAGE = 200
            // Change this to the damage type of the lightning shield. You might want to make it ATTACK_TYPE_MAGIC
            private constant attacktype CLS_DAMAGE_CLASS = ATTACK_TYPE_NORMAL
            private hashtable chargesHashtable
            private trigger castsCLSTrig = CreateTrigger()
        endglobals
       
        private function unitIsAttacked takes nothing returns nothing
            local unit attackee = GetTriggerUnit()
            local unit attacker = GetAttacker()
            local integer charges
           
            set charges = LoadInteger(chargesHashtable, 0, GetHandleId(attackee))
            call UnitDamageTarget(attackee, attacker, ORB_DAMAGE, true, false, CLS_DAMAGE_CLASS, DAMAGE_TYPE_LIGHTNING, WEAPON_TYPE_WHOKNOWS)
            set charges = charges - 1
            if (charges == 0) then
                call UnitRemoveAbility(attackee, 'B000')
                call DestroyTrigger(GetTriggeringTrigger())
            else
                call SaveInteger(chargesHashtable, 0, GetHandleId(attackee), charges)
            endif
       
            set attackee = null
            set attacker = null
        endfunction
       
        private function unitGainsCLS takes nothing returns nothing
            local unit u = GetTriggerUnit()
            local trigger t = CreateTrigger()
           
            call SaveInteger(chargesHashtable, 0, GetHandleId(u), MAX_CHARGES)
            call TriggerAddAction(t, function unitIsAttacked)
            call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_ATTACKED)
           
            set t = null
            set u = null
        endfunction
       
        private function unitGainsCLSFilter takes nothing returns boolean
            if (GetSpellAbilityId() == 'A000') then
                return true
            endif
            return false
        endfunction

        private function init takes nothing returns nothing
            set chargesHashtable = InitHashtable()
            call TriggerRegisterAnyUnitEventBJ(castsCLSTrig, EVENT_PLAYER_UNIT_SPELL_EFFECT)
            call TriggerAddCondition(castsCLSTrig, function unitGainsCLSFilter)
            call TriggerAddAction(castsCLSTrig, function unitGainsCLS)
        endfunction
       
    endlibrary
     
  4. Adiktuz

    Adiktuz

    Joined:
    Oct 16, 2008
    Messages:
    9,674
    Resources:
    23
    Models:
    2
    Packs:
    1
    Maps:
    1
    Spells:
    16
    Tutorials:
    1
    JASS:
    2
    Resources:
    23
    checked the code... seems okay though it would damage the unit once it starts to attack so even if it stops the attack before it can even damage the user, the attacker will still get damaged, but I dont think that's some big issue...

    also each cast of this would reset the charges to 3, I think it would be better if you make the charges stackable by doing this...

    Code (vJASS):

    private function unitGainsCLS takes nothing returns nothing
            local unit u = GetTriggerUnit()
            local trigger t = CreateTrigger()
            local integer charge = LoadInteger(chargesHashtable, 0, GetHandleId(u))
           
            call SaveInteger(chargesHashtable, 0, GetHandleId(u), MAX_CHARGES + charge)
            call TriggerAddAction(t, function unitIsAttacked)
            call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_ATTACKED)
           
            set t = null
            set u = null
        endfunction
     


    or even better, add a boolean in the globals section to check whether he wants the charges to stack or not...
    Code (vJASS):

    //TESH.scrollpos=0
    //TESH.alwaysfold=0
    library ChargedLightningShield initializer init

        globals
            // Change this to the number of charges you want the lightning shield to have
            private constant integer MAX_CHARGES = 3
            // Change this to the base damage of the orbs
            private constant integer ORB_DAMAGE = 200
            // Settings this to true will stack the number of charges
            private constant boolean CHARGE_STACK = true
            // Change this to the damage type of the lightning shield. You might want to make it ATTACK_TYPE_MAGIC
            private constant attacktype CLS_DAMAGE_CLASS = ATTACK_TYPE_NORMAL
            private hashtable chargesHashtable
            private trigger castsCLSTrig = CreateTrigger()
        endglobals
       
        private function unitIsAttacked takes nothing returns nothing
            local unit attackee = GetTriggerUnit()
            local unit attacker = GetAttacker()
            local integer charges
           
            set charges = LoadInteger(chargesHashtable, 0, GetHandleId(attackee))
            call UnitDamageTarget(attackee, attacker, ORB_DAMAGE, true, false, CLS_DAMAGE_CLASS, DAMAGE_TYPE_LIGHTNING, WEAPON_TYPE_WHOKNOWS)
            set charges = charges - 1
            if (charges == 0) then
                call UnitRemoveAbility(attackee, 'B000')
                call DestroyTrigger(GetTriggeringTrigger())
            else
                call SaveInteger(chargesHashtable, 0, GetHandleId(attackee), charges)
            endif
       
            set attackee = null
            set attacker = null
        endfunction
       
        private function unitGainsCLS takes nothing returns nothing
            local unit u = GetTriggerUnit()
            local trigger t = CreateTrigger()
            local integer charge = LoadInteger(chargesHashtable, 0, GetHandleId(u))

            if CHARGE_STACK then
               call SaveInteger(chargesHashtable, 0, GetHandleId(u), MAX_CHARGES + charge)
            else
               call SaveInteger(chargesHashtable, 0, GetHandleId(u), MAX_CHARGES)
            endif
            call TriggerAddAction(t, function unitIsAttacked)
            call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_ATTACKED)
           
            set t = null
            set u = null
        endfunction
       
        private function unitGainsCLSFilter takes nothing returns boolean
            if (GetSpellAbilityId() == 'A000') then
                return true
            endif
            return false
        endfunction

        private function init takes nothing returns nothing
            set chargesHashtable = InitHashtable()
            call TriggerRegisterAnyUnitEventBJ(castsCLSTrig, EVENT_PLAYER_UNIT_SPELL_EFFECT)
            call TriggerAddCondition(castsCLSTrig, function unitGainsCLSFilter)
            call TriggerAddAction(castsCLSTrig, function unitGainsCLS)
        endfunction
       
    endlibrary
     
     
  5. Catch_ya

    Catch_ya

    Joined:
    May 21, 2009
    Messages:
    982
    Resources:
    1
    Spells:
    1
    Resources:
    1
    Code (vJASS):
    set chargesHashtable = InitHashtable()

    should be declared when you make the global.
    Code (vJASS):
    private hashtable chargesHashtable = InitHashtable()


    And instead of this
    Code (vJASS):
        private function unitGainsCLSFilter takes nothing returns boolean
            if (GetSpellAbilityId() == 'A000') then
                return true
            endif
            return false
        endfunction

    Could be much easier.
    Code (vJASS):
        private function unitGainsCLSFilter takes nothing returns boolean
            return GetSpellAbilityId() == 'A000' then
        endfunction

    Now you also know that for next time. :)

    Also why do you use a global trigger? Why not:

    Code (vJASS):
        private function init takes nothing returns nothing
            local trigger t = CreateTrigger()
            call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
            call TriggerAddCondition(t, function unitGainsCLSFilter)
            call TriggerAddAction(t, function unitGainsCLS)
        endfunction


    'B000' should also be editable as a global integer.

    Hope I helped, and I hope you learned something.
     
  6. Adiktuz

    Adiktuz

    Joined:
    Oct 16, 2008
    Messages:
    9,674
    Resources:
    23
    Models:
    2
    Packs:
    1
    Maps:
    1
    Spells:
    16
    Tutorials:
    1
    JASS:
    2
    Resources:
    23
    I think you should also check whether the unit still has the buff before you do the damage because of the fact that some spells can remove buff... I cannot add it now coz I cant afford to put a wrong code since I'm not with my WE right now...

    Also, move the SaveInteger to outside the if-then-else because initially you placed it in the else which would bug since it would not save the value 0...

    One more thing, you made a new trigger for each unit, with each cast... you can use only one trigger that would already work for all units but you would need to add a filter to the action that would check the remaining charges and if the unit still has buff (cause of the possibility of being purged/dispelled) before you do the damage...
     
  7. Teelo

    Teelo

    Joined:
    Mar 31, 2009
    Messages:
    709
    Resources:
    1
    Maps:
    1
    Resources:
    1
    True, I forgot about it being purged, thanks.

    What do you mean about a unit stopping its attack? How can a unit start attacking then stop before taking the damage?
     
  8. Inferior

    Inferior

    Joined:
    Nov 3, 2008
    Messages:
    110
    Resources:
    3
    Icons:
    1
    Spells:
    2
    Resources:
    3
    there is a difference between attacking a unit and damaging a unit. Thats why there are 2 Events.

    Attacking a unit means giving the order to a unit to attack another, and when the attackanimation starts. Thats an attack.

    Damaging a unit is right in that moment a unit takes damage.

    So 'Damaging' not equal 'Attack'.

    Means if you spam S ( Stop ) , each time the unit starts a new Attack(animation) the unit will be damaged (by your spell). If you know 'Berserker Call' from DotA's Axe, maybe you know that if you spam the s button you make him spin even more because that spinning skill allways triggers if an attacking unit starts an attack.

    I hope i made this clear o_O

    ~Inferior
     
  9. Teelo

    Teelo

    Joined:
    Mar 31, 2009
    Messages:
    709
    Resources:
    1
    Maps:
    1
    Resources:
    1
    So... should I be using "a unit is damaged" instead of "a unit is attacked"?

    Uploaded v1.1.
    Changes:
    - When a unit is attacked, it will be checked if it has the buff still. If the buff is gone, all data will be removed, and the attacker won't be damaged.
    - Added the option to allow the charges to stack when you recast Charged Lightning Shield.

    The JASS
    Code (vJASS):
    library ChargedLightningShield initializer init

        globals
            // Change this to the number of charges you want the lightning shield to have when it is cast
            private constant integer CLS_ONCAST_CHARGES = 3
            // Change this to the maximum number of charges the lightning shield can have (-1 for unlimited)
            private constant integer CLS_MAX_CHARGES = 10
            // Change this to the base damage of the orbs
            private constant integer ORB_DAMAGE = 200
            // Change this to the damage type of the lightning shield. You might want to make it ATTACK_TYPE_MAGIC
            private constant attacktype CLS_DAMAGE_CLASS = ATTACK_TYPE_NORMAL
            // Change this to true if you want the shield charges to stack
            private constant boolean CLS_STACKS = false
            // Change this to the ability code of the lightning shield
            private constant integer CLS_ABILITY_CODE = 'A000'
            // Change this to the buff code of the lightning shield
            private constant integer CLS_BUFF_CODE = 'B000'
            private hashtable chargesHashtable = InitHashtable()
            private hashtable isAttackedHashtable = InitHashtable()
        endglobals
       
        private function unitIsAttacked takes nothing returns nothing
            local unit attackee = GetTriggerUnit()
            local unit attacker = GetAttacker()
            local integer charges = LoadInteger(chargesHashtable, 0, GetHandleId(attackee))
            local boolean hasBuff = (GetUnitAbilityLevel(attackee, CLS_BUFF_CODE) > 0)
           
            set charges = charges - 1
           
            if (not hasBuff or charges == 0) then
                // The buff was dispelled or expired or it should be dispelled now
                call SaveInteger(chargesHashtable, 0, GetHandleId(attackee), 0)
                call DestroyTrigger(GetTriggeringTrigger())
                call SaveTriggerHandle(isAttackedHashtable, 0, GetHandleId(attackee), null)
            endif
           
            if (hasBuff and charges == 0) then
                call UnitRemoveAbility(attackee, CLS_BUFF_CODE)
            endif
           
            if (hasBuff) then
                call UnitDamageTarget(attackee, attacker, ORB_DAMAGE, true, false, CLS_DAMAGE_CLASS, DAMAGE_TYPE_LIGHTNING, WEAPON_TYPE_WHOKNOWS)
            endif
           
            if (charges > 0) then
                call SaveInteger(chargesHashtable, 0, GetHandleId(attackee), charges)
            endif
       
            set attackee = null
            set attacker = null
        endfunction
       
        private function unitGainsCLS takes nothing returns nothing
            local unit u = GetTriggerUnit()
            local trigger t
            local integer charges = CLS_ONCAST_CHARGES
           
            set t = LoadTriggerHandle(isAttackedHashtable, 0, GetHandleId(u))
            if (t == null) then
                set t = CreateTrigger()
                call TriggerAddAction(t, function unitIsAttacked)
                call TriggerRegisterUnitEvent(t, u, EVENT_UNIT_ATTACKED)
                call SaveTriggerHandle(isAttackedHashtable, 0, GetHandleId(u), t)
            endif
           
            if (CLS_STACKS and GetUnitAbilityLevel(u, CLS_BUFF_CODE) > 0) then
                set charges = charges + LoadInteger(chargesHashtable, 0, GetHandleId(u))
            endif
            call SaveInteger(chargesHashtable, 0, GetHandleId(u), charges)
           
            set t = null
            set u = null
        endfunction
       
        private function unitGainsCLSFilter takes nothing returns boolean
            return (GetSpellAbilityId() == CLS_ABILITY_CODE)
        endfunction

        private function init takes nothing returns nothing
            local trigger t = CreateTrigger()
            call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
            call TriggerAddCondition(t, function unitGainsCLSFilter)
            call TriggerAddAction(t, function unitGainsCLS)
            set t = null
        endfunction
       
    endlibrary
     
  10. Adiktuz

    Adiktuz

    Joined:
    Oct 16, 2008
    Messages:
    9,674
    Resources:
    23
    Models:
    2
    Packs:
    1
    Maps:
    1
    Spells:
    16
    Tutorials:
    1
    JASS:
    2
    Resources:
    23
    not takes precedence to everything so I guess your filter should be
    Code (vJASS):

    if ((not hasBuff) or charges == 0) then
     


    also why set charges to charges - 1 at the start? I think that should be after the actions... also remove the buff when charges become zero...
     
  11. Teelo

    Teelo

    Joined:
    Mar 31, 2009
    Messages:
    709
    Resources:
    1
    Maps:
    1
    Resources:
    1
    I believe
    if (not hasBuff or charges == 0) then
    is working exactly as I want it to.

    Code (vJASS):
    if (hasBuff and charges == 0) then
        call UnitRemoveAbility(attackee, CLS_BUFF_CODE)
    endif

    is removing the buff when the charges are zero.
     
    Last edited: Mar 19, 2010
  12. Adiktuz

    Adiktuz

    Joined:
    Oct 16, 2008
    Messages:
    9,674
    Resources:
    23
    Models:
    2
    Packs:
    1
    Maps:
    1
    Spells:
    16
    Tutorials:
    1
    JASS:
    2
    Resources:
    23
    I just read about the "not" in some thread...

    I didn't saw it... sorry... ^^

    anyway, since you make a new trigger for each unit I think it would be better to use Unit - Takes Damage event so that it will only damage the unit once the attack hits.
     
  13. Teelo

    Teelo

    Joined:
    Mar 31, 2009
    Messages:
    709
    Resources:
    1
    Maps:
    1
    Resources:
    1
    Well apparently I'm supposed to replace it with a damage detection system.
     
  14. Adiktuz

    Adiktuz

    Joined:
    Oct 16, 2008
    Messages:
    9,674
    Resources:
    23
    Models:
    2
    Packs:
    1
    Maps:
    1
    Spells:
    16
    Tutorials:
    1
    JASS:
    2
    Resources:
    23
    yeah, I saw TriggerHappy's review... ^^