| 09-12-2008, 02:03 PM | #1 |
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 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 ! 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 |
Use Dusk's dds. |
| 09-12-2008, 02:36 PM | #3 | |
Quote:
|
| 09-12-2008, 02:41 PM | #4 |
| 09-12-2008, 02:52 PM | #5 |
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 |
no, there isn't, damage detection implies dynamic triggers. Or try my unit DD system: 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 |
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 |
I hope this example gives you an idea: 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 | |
Quote:
|
| 09-12-2008, 07:46 PM | #10 | |
Quote:
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 |
Just one tip: Never use call UnitDamageTarget(...) inside a condition, because it causes and infinite loop. |
| 09-12-2008, 08:43 PM | #12 | |
Quote:
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 |
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 | |
Quote:
|
| 09-12-2008, 09:56 PM | #15 |
So...
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. |
