Template On Attack Template 1.30

emjlr3

Change can be a good thing
Reaction score
395
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

  • attack temp.JPG
    attack temp.JPG
    178.7 KB · Views: 1,764
  • emjlr3 - On Attack Template 1.30.w3x
    110 KB · Views: 616

ayumilove

Youtube account suspended! youtube.com/ayumilove8
Reaction score
110
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=~
Reaction score
177
....

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
Reaction score
395
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
Reaction score
111
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
Reaction score
395
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
Reaction score
203
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=~
Reaction score
177
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
Reaction score
395
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
Reaction score
33
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
Reaction score
92
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
Reaction score
395
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
Reaction score
92
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
Reaction score
395
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~

† Ғσſ ŧħə ѕαĸε Φƒ ~Ğ䣚~ †
Reaction score
180
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
Reaction score
395
coded in JASS, written with GUIers in mind
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Varine Varine:
    I ordered like five blocks for 15 dollars. They're just little aluminum blocks with holes drilled into them
  • Varine Varine:
    They are pretty much disposable. I have shitty nozzles though, and I don't think these were designed for how hot I've run them
  • Varine Varine:
    I tried to extract it but the thing is pretty stuck. Idk what else I can use this for
  • Varine Varine:
    I'll throw it into my scrap stuff box, I'm sure can be used for something
  • Varine Varine:
    I have spare parts for like, everything BUT that block lol. Oh well, I'll print this shit next week I guess. Hopefully it fits
  • Varine Varine:
    I see that, despite your insistence to the contrary, we are becoming a recipe website
  • Varine Varine:
    Which is unique I guess.
  • The Helper The Helper:
    Actually I was just playing with having some kind of mention of the food forum and recipes on the main page to test and see if it would engage some of those people to post something. It is just weird to get so much traffic and no engagement
  • The Helper The Helper:
    So what it really is me trying to implement some kind of better site navigation not change the whole theme of the site
  • Varine Varine:
    How can you tell the difference between real traffic and indexing or AI generation bots?
  • The Helper The Helper:
    The bots will show up as users online in the forum software but they do not show up in my stats tracking. I am sure there are bots in the stats but the way alot of the bots treat the site do not show up on the stats
  • Varine Varine:
    I want to build a filtration system for my 3d printer, and that shit is so much more complicated than I thought it would be
  • Varine Varine:
    Apparently ABS emits styrene particulates which can be like .2 micrometers, which idk if the VOC detectors I have can even catch that
  • Varine Varine:
    Anyway I need to get some of those sensors and two air pressure sensors installed before an after the filters, which I need to figure out how to calculate the necessary pressure for and I have yet to find anything that tells me how to actually do that, just the cfm ratings
  • Varine Varine:
    And then I have to set up an arduino board to read those sensors, which I also don't know very much about but I have a whole bunch of crash course things for that
  • Varine Varine:
    These sensors are also a lot more than I thought they would be. Like 5 to 10 each, idk why but I assumed they would be like 2 dollars
  • Varine Varine:
    Another issue I'm learning is that a lot of the air quality sensors don't work at very high ambient temperatures. I'm planning on heating this enclosure to like 60C or so, and that's the upper limit of their functionality
  • Varine Varine:
    Although I don't know if I need to actually actively heat it or just let the plate and hotend bring the ambient temp to whatever it will, but even then I need to figure out an exfiltration for hot air. I think I kind of know what to do but it's still fucking confusing
  • The Helper The Helper:
    Maybe you could find some of that information from AC tech - like how they detect freon and such
  • Varine Varine:
    That's mostly what I've been looking at
  • Varine Varine:
    I don't think I'm dealing with quite the same pressures though, at the very least its a significantly smaller system. For the time being I'm just going to put together a quick scrubby box though and hope it works good enough to not make my house toxic
  • Varine Varine:
    I mean I don't use this enough to pose any significant danger I don't think, but I would still rather not be throwing styrene all over the air

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top