HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Custom spell resistance problem

06-15-2008, 01:58 PM#1
cohadar
Ok I have a resistance library with one condition

Collapse JASS:
library Resistance uses TextTag

globals
    private constant integer CHANCE = 33
endglobals

public function Conditions takes nothing returns boolean
    if GetUnitAbilityLevel(GetSpellTargetUnit(), AID_ORB_RESISTANCE)>0 then
        if GetRandomInt(1, 100)<=CHANCE then
            call TextTag_Unit(GetSpellTargetUnit(), "RESISTED!", "|c006600FF")
            return false
        endif
    endif
    return true
endfunction

endlibrary

Then I add that condition to any targeted spell that I want to fail if target unit has custom resistance ability:
Collapse JASS:
    call TriggerRegisterAnyUnitEventBJ(trig, EVENT_UNIT_SPELL_EFFECT)
    call TriggerAddCondition( trig, Condition( function Conditions ) )
    call TriggerAddCondition( trig, Condition( function Resistance_Conditions ) )
    call TriggerAddAction( trig, function Actions )

Theoretically this should work just fine but it does not,
sometimes (randomly) it says RESISTED! but the spell is still executed.
How is this possible? I thought multiple conditions on a trigger use AND
06-15-2008, 02:07 PM#2
Vexorian
Quote:
I thought multiple conditions on a trigger use AND
That's one of the things nobody bothered to test yet.

So, make 4 tests with 2 conditions, test true * true, true * false, false * true and false * false, and see what happens.
06-15-2008, 05:36 PM#3
cohadar
Yes like I expected only true*true fires the action, all others fail.
Hmmmmm... So where could the error be than?
06-16-2008, 04:50 AM#4
Spec
Hmm, I tested library with this code, and it seems to work fine:
Collapse JASS:
scope test
private function Conditions takes nothing returns boolean
    return true
endfunction

private function Actions takes nothing returns nothing
    call UnitDamageTarget(GetSpellAbilityUnit(), GetSpellTargetUnit(), 100.0, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS)
    call BJDebugMsg("blah")
endfunction

//===========================================================================
public function InitTrig takes nothing returns nothing
    local trigger tr = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(tr, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(tr, Condition(function Conditions))
    call TriggerAddCondition(tr, Condition(function Resistance_Conditions))
    call TriggerAddAction(tr, function Actions)
endfunction
endscope

There is no damage dealt to target, when "Resisted!" fires.

Quote:
multiple conditions on a trigger use AND
It's just definitely true.
06-16-2008, 05:14 AM#5
Vexorian
He said 'sometimes'

Could it be that TextTag_Unit is doing something silly? What happens with conditions when the thread crashes, does wc3 consider it as false? Also, check out the result compiled script.
06-16-2008, 06:40 AM#6
cohadar
Collapse JASS:
//===========================================================================
function TextTag_Unit takes unit whichUnit,string text,string color returns nothing
    local texttag t= CreateTextTag()
    local integer shift= IMinBJ(StringLength(text) , TextTag___MAX_TEXT_SHIFT) * TextTag___MEAN_CHAR_WIDTH
   
    call SetTextTagText(t , color + text , TextTag___FONT_SIZE)
    call SetTextTagPos(t , GetUnitX(whichUnit) - shift , GetUnitY(whichUnit) , TextTag___HEIGHT)
    call SetTextTagVelocity(t , TextTag___VELOCITY_X , TextTag___VELOCITY_Y)
    call SetTextTagVisibility(t , true)
    call SetTextTagFadepoint(t , TextTag___FADE_POINT)
    call SetTextTagLifespan(t , TextTag___LIFESPAN)
    call SetTextTagPermanent(t , false)
   
    set t = null
endfunction

compiled script is fine.

Why would a thread that runs conditions crash, and if it crashed why it executed actions?


I tried this approach:
Collapse JASS:
library Resistance initializer Init uses TextTag

globals
    private constant integer CHANCE = 33
    
    private trigger trig = CreateTrigger()
endglobals

//===========================================================================
public function Conditions takes nothing returns boolean
    if GetUnitAbilityLevel(GetSpellTargetUnit(), AID_ORB_RESISTANCE)>0 then
        if GetRandomInt(1, 100)<=CHANCE then
            call TriggerExecute(trig)
            return false
        endif
    endif
    return true
endfunction

//===========================================================================
private function DisplayTextTag takes nothing returns nothing
    call TextTag_Unit(GetSpellTargetUnit(), "RESISTED!", "|c006600FF")
endfunction

//===========================================================================
private function Init takes nothing returns nothing
    call TriggerAddAction(trig, function DisplayTextTag)
endfunction

endlibrary

and got the exact same result, sometimes it works, sometimes it doesn't ......
once is resists properly, once it does not resist, once it both resists and executes spell .....

My only guess is that Resistance_Conditions is returning true after TextTag but I have no idea why....

EDIT:
===========================================
So I was doing some debugging:
Collapse JASS:
//===========================================================================
public function Conditions takes nothing returns boolean
    if GetUnitAbilityLevel(GetSpellTargetUnit(), AID_ORB_RESISTANCE)>0 then
        if GetRandomInt(1, 100)<=CHANCE then
            call TriggerExecute(trig)
            return false
        else
            call BJDebugMsg("Unit did not resist!")
            return true
        endif
    else
        call BJDebugMsg("Unit has no resistance!")
        return true
    endif
    
    call BJDebugMsg("Not supposed to happen!")
    return true
endfunction

And guess what, when unit actually resists (executes texttag trig) it displays "Unit did not resist!"
Roflmao.
So trigger execution somehow slipped through the if ....
06-16-2008, 07:35 AM#7
cohadar
I found a good solution:
Collapse JASS:
library Resistance initializer Init uses TextTag

globals
    public trigger trig = CreateTrigger()
    
    private constant integer CHANCE = 33
endglobals

//===========================================================================
private function Conditions takes nothing returns boolean
    if GetUnitAbilityLevel(GetSpellTargetUnit(), AID_ORB_RESISTANCE)>0 then
        if GetRandomInt(1, 100)<=CHANCE then
            call TextTag_Unit(GetSpellTargetUnit(), "RESISTED!", "|c006600FF")
            return false
        endif
    endif
    
    return true
endfunction

//===========================================================================
private function Init takes nothing returns nothing
    call TriggerAddCondition(trig, Condition(function Conditions))
endfunction

endlibrary

Collapse JASS:
//===========================================================================
private function Conditions takes nothing returns boolean
    if GetSpellAbilityId() == AID_SPELL then
        return TriggerEvaluate(Resistance_trig)
    endif
    return false
endfunction

The error was caused by the fact that all conditions on trigger are always evaluated no matter if any one of them returned false.
(trigger conditions behave as AND operation but do not do AND optimization)