Template On Attack Template 1.30

emjlr3

Change can be a good thing
Staff member
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!
 

Attachments

ayumilove

Youtube account suspended! youtube.com/ayumilove8
could please explain in detail about this on attack system?

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

uberfoop

~=Admiral Stukov=~
....

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

emjlr3

Change can be a good thing
Staff member
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
 

lh2705

Just another Helper
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
Wtf? Are you serious? Thats not fair at all, well only if your playing a samehero game... :D
 

emjlr3

Change can be a good thing
Staff member
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 :)
 

elmstfreddie

The Finglonger
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...
 

uberfoop

~=Admiral Stukov=~
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...
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.
 

emjlr3

Change can be a good thing
Staff member
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!
 

gref

New Member
That frost spell is one of the coolest spells I have ever seen.

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

Arkan

Nobody rides for free
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?
 

emjlr3

Change can be a good thing
Staff member
not sure what you mean there...I guess however that that would leak a good bit more though, and be slower
 

Arkan

Nobody rides for free
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?
 

emjlr3

Change can be a good thing
Staff member
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
 

~GaLs~

† Ғσſ ŧħə ѕαĸε Φƒ ~Ğ䣚~ †
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
 

emjlr3

Change can be a good thing
Staff member
coded in JASS, written with GUIers in mind
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • The Helper The Helper:
    My grandmother just passed away, she was 95. I might be going to Florida for a week.
  • The Helper The Helper:
    I have a buddy in Florida who has an extra office space for me with a computer so I can do anything so likely I will be going up there wednesday or thursday
  • Ghan Ghan:
    Let me know if there's anything I can do to help.
  • The Helper The Helper:
    thank you Ghan
  • jonas jonas:
    Sorry for your loss
    +1
  • Varine Varine:
    I'm sorry to hear that bro
  • Varine Varine:
    Not to distract but is anyone aware of any software to help visually impaired people interact with their PC?
  • Varine Varine:
    Also what's the best way to ship a PC? Should I just wrap the fuck out of it in the case or put the components in static bags and wrapped up individually?
  • Ghan Ghan:
    The GPU is the biggest danger typically.
  • Ghan Ghan:
    Some of the pre-built vendors use expanding foam to fill in the case and secure the GPU. Otherwise it might be best to remove it and ship it separately.
  • Ghan Ghan:
    Similar if the machine has a large tower CPU cooler installed. Those can experience huge forces and destroy the socket during shipment if they are heavy.
  • Varine Varine:
    So mainly just the heavier things that jut out? I'm planning on pulling out the SSD's too and anything that I don't have well secured. I'll probably be good leaving the motherboard and PSU screwed in there though if I bundle it up?
  • Ghan Ghan:
    Yeah, I'd expect those to be fine. It's mainly the heavy stuff that is also long/tall where dropping the case would cause it to exert a ton of force on the mount. The motherboard will be fine screwed into the board unless the case itself is somehow severely damaged.
  • Varine Varine:
    I have the original packaging for it, so I was going to just put it back in there
  • Varine Varine:
    I don't think I have the boxes for the components though and so I don't want to have a bunch of loose shit bouncing around
  • The Helper The Helper:
    damn I just read that lol
  • The Helper The Helper:
    when i read up and saw spray in foam I was like oh shit
  • The Helper The Helper:
    going to do the last controller giveaway in the NUON Dome forum because I just cannot sell them since I got them for free from a deceased NUON Legend. It is my last one from that.

    Members online

    No members online now.

    Affiliates

    Hive Workshop NUON Dome
    Top