HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

[OLY] LightShield - Coding solution needed !!!

09-12-2008, 02:03 PM#1
Flame_Phoenix
Hi guys, I am making a shield ability that prevents the user from taking damage, and then in the end of its duration, it gives the user the shield's not used hp points in healing.

I am using a new thing to me
Collapse JASS:
call TriggerRegisterUnitEvent (LightShieldTrg, targ, EVENT_UNIT_DAMAGED )

And, for good coding, I am using it on the Init function, where all triggers should be set.

However I have a problem ... this event takes a unit !!!
I don't see a way to fix this without using dynamic triggers, but I know they are evil !
Please some one help me find a solution !

Collapse full code:
//Uses TimerUtils so far
scope LightShield initializer Init
    globals
        private constant integer AID = 'A001'
    endglobals
    
    private constant function Duration takes integer level returns real
        return level * 20.
    endfunction
    
    private constant function DamageAbsorbed takes integer level returns real
        return level * 100.
    endfunction
//===========================================================================
    private struct MyStruct 
        unit caster
        unit target
        integer level
        timer dur
        
        static method create takes unit caster, unit target, integer level returns MyStruct
            local MyStruct data = MyStruct.allocate()
            
            set data.caster = caster
            set data.level = level
            set data.target = target
            set data.dur = NewTimer()
            
            return data
        endmethod
        
        method onDestroy takes nothing returns nothing
            call ReleaseTimer(.dur)
        endmethod
    endstruct
//===========================================================================
    private function onDamage takes nothing returns boolean
        return true
    endfunction
//===========================================================================
    private function PreventDamage takes nothing returns nothing
    endfunction
//===========================================================================
    private function Conditions takes nothing returns boolean
        return GetSpellAbilityId() == AID
    endfunction
//===========================================================================    
    private function Actions takes nothing returns nothing
        local MyStruct data = MyStruct.create(GetTriggerUnit(), GetSpellTargetUnit(), GetUnitAbilityLevel(GetTriggerUnit(), AID))
        
    endfunction
//===========================================================================
    private function Init takes nothing returns nothing
        //when the hero casts the spell
        local trigger LightShieldTrg = CreateTrigger(  )
        call TriggerRegisterAnyUnitEventBJ( LightShieldTrg, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition(LightShieldTrg, Condition(function Conditions))
        call TriggerAddAction(LightShieldTrg, function Actions)
        
        //when the hero takes damage
        set LightShieldTrg = CreateTrigger(  )
        
        //PROBLEM !!! This takes a unit !! how do I make this without a dinamic trigger ?
 //       call TriggerRegisterUnitEvent (LightShieldTrg, targ, EVENT_UNIT_DAMAGED )
        call TriggerAddCondition(LightShieldTrg, Condition(function onDamage))
        call TriggerAddAction(LightShieldTrg, function PreventDamage)
        
        set LightShieldTrg = null
    endfunction
endscope
09-12-2008, 02:32 PM#2
Vestras
Use Dusk's dds.
09-12-2008, 02:36 PM#3
Flame_Phoenix
Quote:
Use Dusk's dds.
what is that ?
09-12-2008, 02:41 PM#4
Alexander244
"Dusk's dds"

Basically event leaks are considered by many a lesser evil than dynamic triggers.
09-12-2008, 02:52 PM#5
Flame_Phoenix
Guy, isn't there other way out ? Like that will force me to use a special function for damage, and I take that into my map, I will have to change ALL spells !

Isn't there anything else I can use, or some other solution ?
09-12-2008, 06:11 PM#6
moyack
no, there isn't, damage detection implies dynamic triggers.

Or try my unit DD system:

Collapse Damage detection Code extracted from my Unit recycler system:
library DamDet

private struct DD // damage detection struct
    static group D // group of unit that will have damage detection
    static trigger T
    
    // Add the attacked unit to the damage detection if the unit is not in the pack
    private static method AddUnit takes nothing returns nothing
        if not IsUnitInGroup(GetTriggerUnit(), DD.D) then
            debug call BJDebugMsg("Added " + GetUnitName(GetTriggerUnit()) + " to the DD")
            call TriggerRegisterUnitEvent(DD.T, GetTriggerUnit(), EVENT_UNIT_DAMAGED)
            call GroupAddUnit(DD.D, GetTriggerUnit())
        endif
    endmethod
    
    private static method onInit takes nothing returns nothing
        set DD.T = CreateTrigger()
        set DD.D = CreateGroup()
        call TriggerRegisterAnyUnitEventBJ(DD.T, EVENT_PLAYER_UNIT_ATTACKED)
        call TriggerAddAction(DD.T, function DD.AddUnit)
        set DD.T = CreateTrigger()
    endmethod
endstruct

// Damage detection system functions...
function AddDamageCondition takes boolexpr b returns nothing
    call TriggerAddCondition(DD.T, b)
endfunction

endlibrary

Here, you only have to add conditions that will be checked every time a unit receives damage. The system automatically add detection to the units which are attacked.
09-12-2008, 06:40 PM#7
Flame_Phoenix
Ok, so How would I know that my hero got attack with your system Moyack ? Can you teach me how to use your system ??

Another question, you mean that DD implies leaks and other dynamic trigger evils ?
09-12-2008, 07:32 PM#8
moyack
I hope this example gives you an idea:

Collapse JASS:
scope VampiricAttack initializer init 

globals
    private constant integer SpellID = 'A000' // the dummy passive ability that emulates vampiric aura
    private constant string HealFx = "" // the heal effect path 
endglobals

private constant function level takes integer l returns real
    return 0.15 + 0.15*(l-1)
endfunction

private function Actions takes nothing returns boolean
    //local unit u = GetTriggerUnit() // is the unit damaged
    local unit d = GetEventDamageSource() // is the attacker unit
    local real dam = GetEventDamage() // is the damage amount
    local real l = GetUnitAbilityLevel(d, SpellID)
    if l > 0 then
        call SetWidgetLife(d, GetWidgetLife(d) + dam * l) // heals the unit in that percentage of damage dealt
        call DestroyEffect(AddSpecialEffectTarget(d, HealFx, "origin"))
    endif
    set d = null
endfunction

private function init takes nothing returns nothing
    // just add the condition to the DD system
    call AddDamageCondition(Condition(function Actions))
endfunction

endscope
09-12-2008, 07:36 PM#9
the-thingy
Quote:
you mean that DD implies leaks
Well, events are added for every unit but if that unit dies and decays (or is removed from the game in some other way), the event still remains even though it has no use (since the unit associated with that event is gone for good)
09-12-2008, 07:46 PM#10
Flame_Phoenix
Quote:
Well, events are added for every unit but if that unit dies and decays (or is removed from the game in some other way), the event still remains even though it has no use (since the unit associated with that event is gone for good)
Can't we just destroy or remove the event like we do with actions ?

Thx Moyack, the example is quite simple, and I think I like this system enough to use it on my map. I was searching for something like this.
So, I just use GetEventDamage() and heal the attacked unit by its value. Thx ! I will (probably) release a spell version tomorrow, If I don't find any problems (which I probably will xD)
09-12-2008, 08:16 PM#11
moyack
Just one tip: Never use call UnitDamageTarget(...) inside a condition, because it causes and infinite loop.
09-12-2008, 08:43 PM#12
Flame_Phoenix
Quote:
Just one tip: Never use call UnitDamageTarget(...) inside a condition, because it causes and infinite loop.
OMG ! That is terrible !!! I use that in all my spells ! In fact that's the only thing I can use in my map !!! NOO

Is there any other system ?
Seriously, why does EVERYTHING have such a bad counter !!!!

Is there any other way to damage a unit without using GetWigetLife and that thing ?
09-12-2008, 09:03 PM#13
Kyrbi0
Are you sure you should be using "Unit deals Damage"? I'm pretty sure that doesn't work.

Unless you're talking about JASS; does anyone know whether it works in GUI?
09-12-2008, 09:07 PM#14
Flame_Phoenix
Quote:
Unless you're talking about JASS; does anyone know whether it works in GUI?
I make no idea if it works in GUI, but hell ya, I am 100% sure that works fine in JASS, it is the only thing I use in my map =)
09-12-2008, 09:56 PM#15
moyack
So...
  • You cast a shield
  • the shield has hitpoints
  • if the shield last the spell duration, the remaining hitpoints becomes into heal.

IT can be done, and if you need to use DD to do Bonus damage, it can be done too, just you have to change the procedure to deal the damage and manage the credits for the killer in other way, but it can be done.