Template On Attack Template 1.30

Discussion in 'Systems and Snippets' started by emjlr3, Feb 2, 2007.

  1. emjlr3

    emjlr3 Change can be a good thing Staff Member

    Ratings:
    +396 / 0 / -0
    I present to you my...

    On Attack Template 1.30:
    a simple system that allows you do to some great things

    What does this do?

    In the absence of a better method for damage detection using GUI;

    This allows you leverage the event "a unit is attacked", and both efficiently and accurately, detect when the target takes damage, and deal effects to said unit.

    Sounds like fun no..??

    Ok then hurry up and try it out!!

    Version History:
    • 1.30 - Updated for 1.24 compatibility, removed dated CSData and CSSafety requirements, re-arranged and shorten code a bit, optimized trigger execution function, added theoretical destroytrigger() bug aversion configurable
    • 1.20b - Updated to CSData and CSSafety 15.0, added in a new demo ability to showcase usage of the On_Attack_Template_Function call, Demo 3 updated slightly, few minor readme/documentation errors updated
    • 1.2 - Ported to vJASS, slightly updated readme, removed demo 4 ability from test map
    • 1.1 - Added greater functionality
    • 1.0 - Initial Release

    JASS:
    library OnAttackTemplate initializer Init
    
    //=====On Attack Template 1.30=====\\
                                                                                                         
    //==Configurables==\\
    globals
        private constant    boolean     AVOID   = true // Experimental method for trying to avoid destroy trigger related handle stack corruption
        private constant    integer     CASTER  = 'n000' // Rawcode of your dummy caster unit (Ctrl+d in object editor)
        private             hashtable   HT      = null // If you have a global hashtable, set it here
        private constant    real        TIME    = 2. // Duration after the attack to disregard effects
    endglobals
    
    //==NO TOUCHING PAST THIS POINT!!!==\\
    //==========================================================================================
    // Needed globals
    globals
        private boolexpr B
    endglobals
    
    // Needed struct
    private struct data
        unit atkr
        timer t
        trigger trig
        string type
        
        integer abilid
        integer lvl
        string order
        
        real dam
        boolean show
        
        string func
        
        // Maybe it works!?!?!
        static method destroytrigger takes trigger trig returns nothing
            call TriggerSleepAction(300.)
            call DestroyTrigger(trig)
        endmethod
        // Clean up
        method destroy takes nothing returns nothing
            call DisableTrigger(.trig)
            call FlushChildHashtable(HT,GetHandleId(.trig))
            static if AVOID then
                call data.destroytrigger.execute(trig)
            else
                call DestroyTrigger(.trig)
            endif
        endmethod
        // Core of the system
        static method effects takes nothing returns boolean
            local data this
            local unit targ
            local unit dum   
            local texttag t       
            
            if GetTriggerEventId()!=EVENT_UNIT_DAMAGED then // Timer expired
                call .destroy()
            elseif GetEventDamage()>.01 then // Negligable damage
                set this=LoadInteger(HT,GetHandleId(GetTriggeringTrigger()),0)
                if GetEventDamageSource()!=.atkr then // Wrong damage do-er
                    return false
                endif
                
                set targ=GetTriggerUnit()
                call DisableTrigger(.trig) 
                
                if .type=="spell" then // Spell cast
                    set dum = CreateUnit(GetOwningPlayer(.atkr),CASTER,GetUnitX(.atkr),GetUnitY(.atkr),0.) 
                    call UnitAddAbility(dum,.abilid)
                    call UnitApplyTimedLife(dum,'BTLF',2.)  
                    call SetUnitAbilityLevel(dum,.abilid,.lvl) 
                    call IssueTargetOrder(dum,.order,targ)            
                    set dum = null
                elseif .type=="damage" then // Damage deal
                    call UnitDamageTarget(.atkr,targ,.dam,false,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_NORMAL,null)     
                    if .show then
                        set t = CreateTextTag()                    
                        call SetTextTagText(t, "+"+I2S(R2I(.dam))+"!", 0.025)
                        call SetTextTagPosUnit(t, targ,15)
                        call SetTextTagColor(t, 255, 0, 0, 255)
                        call SetTextTagVelocity(t, 0, .03)
                        call SetTextTagVisibility(t, true)
                        call SetTextTagFadepoint(t, 2.)
                        call SetTextTagLifespan(t, 2.)
                        call SetTextTagPermanent(t, false)        
                        set t = null
                    endif
                else // Call function
                    call ExecuteFunc(.func)
                endif
                
                set targ = null
            endif
            
            return false
        endmethod
        // Create struct
        static method create takes unit target returns data
            local data this=data.allocate()
            
            set .trig=CreateTrigger()
            call TriggerRegisterUnitEvent(.trig,target,EVENT_UNIT_DAMAGED)
            call TriggerRegisterTimerEvent(.trig,TIME,false)
            call TriggerAddCondition(.trig,B)
            call SaveInteger(HT,GetHandleId(.trig),0,this)
            
            return this
        endmethod
    endstruct
    
    //==User Functions==\\
    function On_Attack_Template_Function takes unit attacker, unit target, string func returns nothing
        local data d = data.create(target)
        
        set d.atkr = attacker
        set d.func = func
        set d.type = "function"
    endfunction
    function On_Attack_Template_Damage takes unit attacker, unit target, real damage, boolean show returns nothing
        local data d = data.create(target)    
        
        set d.atkr = attacker
        set d.dam = damage
        set d.show = show
        set d.type = "damage"
    endfunction
    function On_Attack_Template_Spell takes unit attacker, unit target, integer abil, integer lvl, string order returns nothing 
        local data d = data.create(target)
        
        set d.atkr = attacker
        set d.abilid = abil
        set d.lvl = lvl
        set d.order = order
        set d.type = "spell"
    endfunction
    
    //==Initialization==\\
    private function Init takes nothing returns nothing
        set B=Condition(function data.effects)
        if HT==null then
            set HT=InitHashtable()
        endif
    endfunction
    
    endlibrary

    enjoy!
     

    Attached Files:

    • Like Like x 7
  2. U are a noob

    U are a noob Mega Super Ultra Cool Member

    Ratings:
    +151 / 0 / -0
    +rep

    it looks like 8/10
     
  3. Tinki3

    Tinki3 Special Member

    Ratings:
    +418 / 0 / -0
    This is awesome.

    Gw emjlr3, +rep
     
  4. ayumilove

    ayumilove Youtube account suspended! youtube.com/ayumilove8

    Ratings:
    +110 / 0 / -0
    could please explain in detail about this on attack system?

    i don't really get the point of having it o.o"
     
  5. uberfoop

    uberfoop ~=Admiral Stukov=~

    Ratings:
    +176 / 0 / -0
    ....

    So that you don't have to be like DotA and use orb effect spots that block other on-attack effects.
     
  6. emjlr3

    emjlr3 Change can be a good thing Staff Member

    Ratings:
    +396 / 0 / -0
    normally to do a spell like this is GUI, you would go off the event a unit is attacked

    this can be played with and you cna actually pause ur unit and make it attack real fast, so as to never actually attack, but get the effects, this is an abuse

    what this allows you to do is, detect whe na unit is attack, go through ur conditions, all in GUI, and if they match up, call this with an ability to be cast

    as you can see fro mthe range char. I put into the map, it waits until the damage is done to do the effects, else the spells would be casted before even the projectile left the attacker

    how is this better even more so?

    well to stop this abuse, in DoTA, for ex., with Spirit Breakers Greater Bash

    the main triger is disabled once it fires, and not reenabled unitl after the slide is over

    so not only can there not be multiple slides at the same tiem for different spirit breakers, but it there can only be one slide ever in the game, and one that is over a new one can happen

    pretty shitty if you ask me
     
  7. lh2705

    lh2705 Just another Helper

    Ratings:
    +111 / 0 / -0
    Wtf? Are you serious? Thats not fair at all, well only if your playing a samehero game... :D
     
  8. emjlr3

    emjlr3 Change can be a good thing Staff Member

    Ratings:
    +396 / 0 / -0
    i have thought of ways to further improve this and make it be able to do more things

    i will add major updates and a better readme next week when I have the time to

    until then, more comments please :)
     
  9. elmstfreddie

    elmstfreddie The Finglonger

    Ratings:
    +203 / 0 / -0
    I don't see what's so special about this though... It's just saying if someone gets attacked and the 30% chance happened, then cast the ability...
     
  10. uberfoop

    uberfoop ~=Admiral Stukov=~

    Ratings:
    +176 / 0 / -0
    The 'unit is attacked' event fires on the attack initialization. AKA it allows you to spam the 'stop' button to spam a triggered spell.
    If you use a damage detection trigger w/o proper coding you can make things fire on like, spell casts. Usually not a big deal, but undesireable.



    This is a rather good system.
     
  11. emjlr3

    emjlr3 Change can be a good thing Staff Member

    Ratings:
    +396 / 0 / -0
    basically it allows what all JASS users do for their maps, for the most part, since it is better, to be used by GUI ppl as well

    do this for me

    in the demo map, make a trigger on attack to cast an ability for the ranged hero

    and look at the difference there

    **UPDATED, now with much more functionality and a better read me

    enjoy!
     
  12. Foresector

    Foresector Member

    Ratings:
    +16 / 0 / -0
    Blimmin Brilliant!

    Although, it is sorta hard to edit because I suck at Jass, but that's my fault :p
     
  13. gref

    gref New Member

    Ratings:
    +33 / 0 / -0
    That frost spell is one of the coolest spells I have ever seen.

    No lag, no ugliness, just perfect. (+Rep)
     
  14. Arkan

    Arkan Nobody rides for free

    Ratings:
    +92 / 0 / -0
    I have a question.
    What would the difference be between using a system like this compared to a system where you have a trigger A that adds all units who enters playable map area (triggering unit takes damage) to trigger B where the actual effect is?
     
  15. emjlr3

    emjlr3 Change can be a good thing Staff Member

    Ratings:
    +396 / 0 / -0
    not sure what you mean there...I guess however that that would leak a good bit more though, and be slower
     
  16. Arkan

    Arkan Nobody rides for free

    Ratings:
    +92 / 0 / -0
    What I mean:

    Detect Trigger:
    Code:
    function Trig_addevent_Actions takes nothing returns nothing
        call TriggerRegisterUnitEvent( gg_trg_Spell_A, GetTriggerUnit(), EVENT_UNIT_DAMAGED )
        call TriggerRegisterUnitEvent( gg_trg_Spell_B, GetTriggerUnit(), EVENT_UNIT_DAMAGED )
    endfunction
    
    //===========================================================================
    function InitTrig_addevent takes nothing returns nothing
        set gg_trg_addevent = CreateTrigger(  )
        call TriggerRegisterEnterRectSimple( gg_trg_addevent, GetPlayableMapRect() )
        call TriggerAddAction( gg_trg_addevent, function Trig_addevent_Actions )
    endfunction
    Spell A:
    Code:
    function Trig_Spell_A_Conditions takes nothing returns boolean
    return GetRandomInt(1,100)>80
    endfunction
    
    function Trig_Spell_A_Actions takes nothing returns nothing
        //Spell actions
    endfunction
    
    //===========================================================================
    function InitTrig_Spell_A takes nothing returns nothing
        set gg_trg_Spell_A = CreateTrigger(  )
        call TriggerAddCondition( gg_trg_Spell_A, Condition( function Trig_Spell_A_Conditions ) )
        call TriggerAddAction( gg_trg_Spell_A, function Trig_Spell_A_Actions )
    endfunction
    Spell B:
    Code:
    function Trig_Spell_B_Conditions takes nothing returns boolean
    return GetRandomInt(1,100)>60
    endfunction
    
    function Trig_Spell_B_Actions takes nothing returns nothing
        //Spell actions
    endfunction
    
    //===========================================================================
    function InitTrig_Spell_B takes nothing returns nothing
        set gg_trg_Spell_B = CreateTrigger(  )
        call TriggerAddCondition( gg_trg_Spell_B, Condition( function Trig_Spell_B_Conditions ) )
        call TriggerAddAction( gg_trg_Spell_B, function Trig_Spell_B_Actions )
    endfunction
    Would this be slower and leak more?
     
  17. emjlr3

    emjlr3 Change can be a good thing Staff Member

    Ratings:
    +396 / 0 / -0
    that is theoretically that optimal way to do it

    however, try and get a GUI user to make that work, and then you have issues
     
  18. ~GaLs~

    ~GaLs~ † Ғσſ ŧħə ѕαĸε Φƒ ~Ğ䣚~ †

    Ratings:
    +181 / 0 / -0
    System coded in GUI or JASS ?
    Mind post the code??

    I am having slow internet speed now...(At friends house for few days)
    So i might need to avoid all uneeded download
     
  19. emjlr3

    emjlr3 Change can be a good thing Staff Member

    Ratings:
    +396 / 0 / -0
    coded in JASS, written with GUIers in mind
     
  20. Hatebreeder

    Hatebreeder So many apples

    Ratings:
    +383 / 0 / -0
    Any chance to make this compattible with ABC?
    Or in General, make it vJass compattible? =)
     

Share This Page