Spell Deflect

Discussion in 'Spells' started by The_Kingpin, Dec 2, 2007.

  1. The_Kingpin

    The_Kingpin Member (Who are you and why should I care?)

    Ratings:
    +41 / 0 / -0
    Deflect - Follows JESP standard.

    No screenshot available.

    (Passive) Gives a percent chance to deflect damage taken and distribute a percentage of it to nearby enemies.

    Features:
    -vJass (http://wc3campaigns.net/showthread.php?t=90999)
    -MUI
    -Leakless
    -BJ-Free
    -Customizable
    -Compatible versions for other attachment systems.

    Code: (Stand-Alone)
    JASS:
    //"Deflect" by The_Kingpin
    library SpellDeflect
        //
        // CONFIGURATION
        //
        globals
            //The id of the ability.
            private constant integer Id = 'A000'
            
            //The area of effect that the spell distributes damage to.
            private constant real Aoe = 300
            
            //The effect on affected units.
            private constant string Effect = "Abilities\\Weapons\\Rifle\\RifleImpact.mdl"
            
            //The area of effect art.
            private constant string AoeEffect = "Units\\NightElf\\Wisp\\WispExplode.mdl"
        endglobals
        
        //Chance to proc per level. Add another "Level[<LEVEL>]=<VALUE>" for more levels.
        private function Chance takes integer lvl returns real
            local real array Level
            set Level[lvl] = 0.10
            set Level[1] = 0.15
            set Level[2] = 0.25
            set Level[3] = 0.30
            return Level[lvl]
        endfunction
        
        //The percentage of damage distributed.
        private function Percent takes integer lvl returns real
            local real array Level
            set Level[lvl] = 0.20
            set Level[1] = 0.20
            set Level[2] = 0.30
            set Level[3] = 0.40
            return Level[lvl]
        endfunction
        
        //This is the condition that the spell will run under. This might not 
        //need to be changed, unless you want the spell to affect other units.
        private function Conditions takes unit caster, unit target returns boolean
            return IsUnitEnemy(target,GetOwningPlayer(caster))
        endfunction
        
        //
        //END CONFIGURATION SECTION
        //
        //Don't edit anything past here unless you know what you are doing.
        //
        //
        //
    
        globals
            private integer array db1
            private integer array db2
            private integer array db3
            private integer array db4
            private integer array db5
            private integer Hex = 0x100000
            private integer Size = 8191
        endglobals
        
        private function H2I takes handle h returns integer 
            return h
            return 0
        endfunction
        
        private function Store takes handle h, integer s returns nothing
            local integer id = H2I(h)-Hex
            if id < Size then
                set db1[id] = s
            elseif id < Size*2 then
                set db2[id - Size] = s
            elseif id < Size*3 then
                set db3[id - Size*2] = s
            elseif id < Size*4 then
                set db4[id - Size*3] = s
            elseif id < Size*5 then
                set db5[id - Size*4] = s
            else
                debug call BJDebugMsg("|cffff2222HexHandles: Too many handles for Store()|r")
            endif
        endfunction
        
        private function Recall takes handle h returns integer
            local integer id = H2I(h)-Hex
            if id < Size then
                return db1[id]
            elseif id < Size*2 then
                return db2[id - Size]
            elseif id < Size*3 then
                return db3[id - Size*2]
            elseif id < Size*4 then
                return db4[id - Size*3]
            elseif id < Size*5 then
                return db5[id - Size*4]
            else
                debug call BJDebugMsg("|cffff2222HexHandles: Nonexistant index for Recall()|r")
            endif
            return 0
        endfunction
        
        private struct SpellEffect
            unit Unit
            integer Level
            real Chance
            real Percent
            trigger Trigger = CreateTrigger()
            
            static method Damaged takes nothing returns boolean
                local SpellEffect this = Recall(GetTriggeringTrigger())
                local real damage
                local group g
                local unit u
                if GetRandomReal(0,1) <= this.Chance then
                    set g = CreateGroup()
                    set damage = this.Percent*GetEventDamage()
                    call SetUnitState(this.Unit,UNIT_STATE_LIFE,GetUnitState(this.Unit,UNIT_STATE_LIFE)+GetEventDamage())
                    call GroupEnumUnitsInRange(g,GetUnitX(this.Unit),GetUnitY(this.Unit),Aoe,null)
                    call DestroyEffect(AddSpecialEffect(AoeEffect,GetUnitX(this.Unit),GetUnitY(this.Unit)))
                    loop
                        set u = FirstOfGroup(g)
                        exitwhen u == null
                        if Conditions(this.Unit,u) then
                            call UnitDamageTarget(this.Unit,u,damage,true,false,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_UNIVERSAL,WEAPON_TYPE_WHOKNOWS)
                            call DestroyEffect(AddSpecialEffectTarget(Effect,u,"chest"))
                        endif
                        call GroupRemoveUnit(g,u)
                    endloop
                    call DestroyGroup(g)
                endif
                set g = null
                return false
            endmethod
            
            private method onDestroy takes nothing returns nothing
                call DestroyTrigger(this.Trigger)
                call Store(this.Unit,0)
            endmethod
            
            static method create takes unit U, integer L returns SpellEffect
                local SpellEffect this = SpellEffect.allocate()
                set this.Unit = U
                set this.Level = L
                set this.Chance = Chance(this.Level)
                set this.Percent = Percent(this.Level)
                call TriggerRegisterUnitEvent(this.Trigger,this.Unit,EVENT_UNIT_DAMAGED)
                call TriggerAddCondition(this.Trigger,Condition(function SpellEffect.Damaged))
                call Store(this.Trigger,this)
                return this
            endmethod
        endstruct
                
        function Trig_Spell_Deflect_Conditions takes nothing returns boolean
            return GetLearnedSkill() == Id
        endfunction
    
        function Trig_Spell_Deflect_Actions takes nothing returns nothing
            local SpellEffect this = Recall(GetTriggerUnit())
            if this != 0 then
                call this.destroy()
            endif
            set this = SpellEffect.create(GetTriggerUnit(),GetUnitAbilityLevel(GetTriggerUnit(),Id))
            call Store(GetTriggerUnit(),this)
        endfunction
    
        //===========================================================================
        function InitTrig_Spell_Deflect takes nothing returns nothing
            set gg_trg_Spell_Deflect = CreateTrigger(  )
            call TriggerRegisterAnyUnitEventBJ( gg_trg_Spell_Deflect, EVENT_PLAYER_HERO_SKILL )
            call TriggerAddCondition( gg_trg_Spell_Deflect, Condition( function Trig_Spell_Deflect_Conditions ) )
            call TriggerAddAction( gg_trg_Spell_Deflect, function Trig_Spell_Deflect_Actions )
        endfunction
    endlibrary

    Contains three versions for different attachment systems: Stand-Alone (Nothing extra necessary), HexHandles (The small attachment system I use in my stuff), and ABC / PUI (Systems made by Cohadar).

    Constructive criticism is welcome. :shades:

    Download:
     

    Attached Files:

    • Like Like x 1
  2. Mr.Tutorial

    Mr.Tutorial Hard in the Paint.

    Ratings:
    +42 / 0 / -0
    Sounds like it would be a good spell but I'm not on good computer so I can't use "TEST" to test it. It won't work to just test for me.
     
  3. The_Kingpin

    The_Kingpin Member (Who are you and why should I care?)

    Ratings:
    +41 / 0 / -0
    ...What?
     
  4. Mr.Tutorial

    Mr.Tutorial Hard in the Paint.

    Ratings:
    +42 / 0 / -0
    Sorry let me restate that.

    I was on a computer in which it didn't have the editor to use the "TEST" button in the editor. So I tried just tested the map on single player and lan and it wouldn't work, but I'll test it later, for now +rep for the effort.
     
  5. waaaks!

    waaaks! Zinctified

    Ratings:
    +256 / 0 / -0
    this is simmilar to dota's gravekeeper's cloak....if u make this as a dota spell...this spell will be added to the dota spell index
     
  6. The_Kingpin

    The_Kingpin Member (Who are you and why should I care?)

    Ratings:
    +41 / 0 / -0
    Neat.
    I don't play DotA.
    What's different with Cloak?

    @ Mr.Tutorial: Don't forget this is a passive spell with a 40% chance of procing at level 3...
     
  7. hell_knight

    hell_knight Playing WoW

    Ratings:
    +126 / 0 / -0
    None for the most part
    Somewhat useful but then again can be done very easily in gui with 3? maybe lines of trigger .
     
  8. Hero

    Hero ─║╣ero─

    Ratings:
    +251 / 0 / -0
    Gravekeeper's Cloak

    Causes any damage taken by Visage to be reflected onto all enemies in a 600 AoE.

    Level 1 - 5% of damage.
    Level 2 - 10% of damage.
    Level 3 - 15% of damage.
    Level 4 - 20% of damage.
     
  9. The_Kingpin

    The_Kingpin Member (Who are you and why should I care?)

    Ratings:
    +41 / 0 / -0
    @ hell_knight
    There's no Unit is Damaged event in GUI. And if I tried to do that in JASS, the event can only be registered with a single unit. Then if I had a trigger to create a trigger when a unit learns that spell, I'd need to attach that trigger to the unit and vice versa. Attaching? You bet your sweet bippy it's struct time! :D

    @ Heronumbersblah
    Hmm, maybe I will consider doing that then.
     
  10. hell_knight

    hell_knight Playing WoW

    Ratings:
    +126 / 0 / -0


    Code:
    Trigger - Add to Damage Taken Trigger <gen> the event (Unit - (EnteringUnit) Takes damage)
    

    Code:
    Damage Taken Trigger
        Events
        Conditions
            (Random integer number between 1 and 100) Less than or equal to (10 + (5 x (Level of Defend for (Attacked unit))))
        Actions
            Set temppoint = (Position of (attacked unit))
            Set tempgroup = (Units within 500.00 of temppoint matching (((Matching unit) belongs to an enemy of (Owner of (Attacked unit))) Equal to True))
            Unit Group - Pick every unit in tempgroup and do (Unit - Cause (Attacked unit) to damage (Picked unit), dealing (Damage taken) damage of attack type Hero and damage type Normal)
            Custom script:   call RemoveLocation (udg_temppoint)
            Custom script:   call RemoveLocation (udg_tempgroup)
    
    Did this in like 30 seconds , so I probaly did mess up but IT IS possible in gui is what I am trying to say.
     
  11. Tinki3

    Tinki3 Special Member

    Ratings:
    +418 / 0 / -0
    Cool spell Kingpin, I like it ;)

    Code seems to be fine, approved.
     
  12. kingkingyyk3

    kingkingyyk3 Visitor (Welcome to the Jungle, Baby!)

    Ratings:
    +216 / 0 / -0
    This spell is broken, it uses H2I
     
  13. SanKakU

    SanKakU Member

    Ratings:
    +21 / 0 / -0
    i think i'm using a spell that is somewhat like this. i'll look into what was done here.
     
  14. Archideas

    Archideas Active Member

    Ratings:
    +31 / 0 / -0
    Is this spell still usable or does it require an update to work with 1.24? ;O
     
  15. Laiev

    Laiev Hey Listen!!

    Ratings:
    +187 / 0 / -0
    JASS:
        private function H2I takes handle h returns integer 
            return h
            return 0
        endfunction


    >>

    JASS:
        private function H2I takes handle h returns integer 
            return GetHandleId(h)
        endfunction


    and should work... at least the code
     
    • Like Like x 1
  16. Archideas

    Archideas Active Member

    Ratings:
    +31 / 0 / -0
    Does seem to fix the stand alone version, at least. Thanks for that, Laiev!

    Another question, though. How do I change it so it only affects organic units? xP
     
  17. Prince.Zero

    Prince.Zero New Member

    Ratings:
    +1 / 0 / -0
    First of... You should really make this multi level instanceable
    giving the user a constant for base reflection value and another for increment reflection value.

    JASS:
        private function H2I takes handle h returns integer 
            return h
            return 0
        endfunction


    OUCH!!! Don't use this! it's only for v1.23 and earlier
    use
    return GetHandleId(h)


    JASS:
            private integer array db1
            private integer array db2
            private integer array db3
            private integer array db4
            private integer array db5


    not really needed
    use 1 array or hashtables for most of your array variables

    JASS:
    function InitTrig_Spell_Deflect takes nothing returns nothing


    you should rename this
    initialize the function from the library declaration

    JASS:
    library SpellDeflect initializer init
    
    private function init takes nothing returns nothing


    thats because you don't want your function name to come in conflict if someone is already using a trigger called Spell Deflect
    Same goes for the trigger
    use local handles

    JASS:
            private method onDestroy takes nothing returns nothing
                call DestroyTrigger(this.Trigger)
                call Store(this.Unit,0)
            endmethod


    this may cause errors.
    you shouldn't really destroy a trigger immediately...
    let me point through a nice method

    JASS:
    globals
        private trigger lasttrigger
    endglobals
    
    function ClearTrigger takes nothing returns nothing
        local trigger t = lasttrigger
        call DisableTrigger(t)
        set lasttrigger = null
        call TriggerSleepAction(60)
        call DestroyTrigger(t)
        set t= null
    endfunction 
    
            private method onDestroy takes nothing returns nothing
                set lasttrigger = this.Trigger
                call ExecuteFunc("ClearTrigger")
                call Store(this.Unit,0)
            endmethod


    ehm, Don't worry about the TriggerSleepAction =] it runs on a different thread.
    ehm... JASS has it's flows. so we must first disable the trigger.
    it happens that there is a chance to screw things if you instantly destroy a trigger without disabling it and wait some time.
    ;o

    hmm
    Due to my honesty i'll rate
    3/5 since your coding method is a bit poor
    it could be done better
     
  18. Laiev

    Laiev Hey Listen!!

    Ratings:
    +187 / 0 / -0
    ....

    honesty you can't judge a spell made on December 2nd, 2007, 04:45 PM that was never updated... also the author of this Last Activity: January 4th, 2009 11:53 AM

    resources we have today, had not previously
     
  19. Prince.Zero

    Prince.Zero New Member

    Ratings:
    +1 / 0 / -0
    then why is it floating around in a useless state?
    Isn't that considered to be garbage?
     
  20. Laiev

    Laiev Hey Listen!!

    Ratings:
    +187 / 0 / -0
    its work and is approved in the past, but now, of course it need more improves to be approved...

    it is only approved until then because it works
     

Share This Page