Spell Deflect

The_Kingpin

Member (Who are you and why should I care?)
Reaction score
41
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:
 

Attachments

  • Spell - Deflect.w3x
    55.6 KB · Views: 834

Mr.Tutorial

Hard in the Paint.
Reaction score
42
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.
 

Mr.Tutorial

Hard in the Paint.
Reaction score
42
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.
 

waaaks!

Zinctified
Reaction score
255
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
 

The_Kingpin

Member (Who are you and why should I care?)
Reaction score
41
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...
 

hell_knight

Playing WoW
Reaction score
126
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...

None for the most part
Somewhat useful but then again can be done very easily in gui with 3? maybe lines of trigger .
 

Hero

─║╣ero─
Reaction score
250
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...

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.
 

The_Kingpin

Member (Who are you and why should I care?)
Reaction score
41
@ 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.
 

hell_knight

Playing WoW
Reaction score
126
@ hell_knight
There's no Unit is Damaged event in GUI.
Plus I did make this as a practice for me.



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.
 

Archideas

Active Member
Reaction score
32
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
 

Prince.Zero

New Member
Reaction score
1
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(&quot;ClearTrigger&quot;)
            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
 

Laiev

Hey Listen!!
Reaction score
188
....

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
 

Laiev

Hey Listen!!
Reaction score
188
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
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top