• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Jass] Boolexpr questions/problems

Status
Not open for further replies.
Level 4
Joined
Aug 12, 2004
Messages
76
Is there a way to keep boolexpr within the main function? Or at least pass on a data to that function?

I am asking because I want to move the unit target into the function that checks the condition. Or better, keep the everything in the main function so that i can use local variables to decide the conditions.

Because I don't want to use "IsUnitEnemy(GetFilterUnit(), Player(0)) == true " but I want to use, "IsUnitEnemy(GetFilterUnit(), GetOwnerofUnit(caster)) == true " or something of the sort. Below is my entire trigger. If that clarifies what I am trying to ask.

JASS:
function Trig_Song_of_Chaos_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A07U' ) ) then
        return false
    endif
    return true
endfunction

function Trig_Song_of_Chaos_Func001002001002003001 takes nothing returns boolean
    return ( IsUnitAliveBJ(GetFilterUnit()) == true )
endfunction

function Trig_Song_of_Chaos_Func001002001002003002 takes nothing returns boolean
    return ( IsUnitEnemy(GetFilterUnit(), Player(0)) == true )
endfunction

function Trig_Song_of_Chaos_Func001002001002003 takes nothing returns boolean
    return GetBooleanAnd( Trig_Song_of_Chaos_Func001002001002003001(), Trig_Song_of_Chaos_Func001002001002003002() )
endfunction

function Trig_Song_of_Chaos_Actions takes nothing returns nothing
    local unit caster = GetSpellAbilityUnit()
    local unit target
    local integer spelllevel = GetUnitAbilityLevel (caster, GetSpellAbilityId())
    local location leak
    local location leak2
    local integer counter = 0
    
    loop
    exitwhen counter == 40
    set leak = GetUnitLoc(caster)
    set target = GroupPickRandomUnit(GetRandomSubGroup(1, GetUnitsInRangeOfLocMatching(500.00, leak, Condition(function Trig_Song_of_Chaos_Func001002001002003))))
    call UnitDamageTargetBJ( caster, target, ( 30.00 * spelllevel ), ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL )
    set leak2 = GetUnitLoc(target)
    call AddSpecialEffectLocBJ( leak2, "Abilities\\Spells\\Human\\MarkOfChaos\\MarkOfChaosTarget.mdl" )
    call DestroyEffect(GetLastCreatedEffectBJ())
    call RemoveLocation(leak)
    call RemoveLocation(leak2)
    set leak = null
    set leak2 = null
    call TriggerSleepAction(0.5)
    set counter = counter + 1
    endloop
    set caster = null
    set target = null
    set leak = null
    set leak2 = null
endfunction

//===========================================================================
function InitTrig_Song_of_Chaos takes nothing returns nothing
    set gg_trg_Song_of_Chaos = CreateTrigger(  )
    call TriggerRegisterUnitEvent( gg_trg_Song_of_Chaos, gg_unit_Hamg_0109, EVENT_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Song_of_Chaos, Condition( function Trig_Song_of_Chaos_Conditions ) )
    call TriggerAddAction( gg_trg_Song_of_Chaos, function Trig_Song_of_Chaos_Actions )
endfunction
 
Last edited by a moderator:
Level 4
Joined
Aug 12, 2004
Messages
76
is there really no other method except for globals? Well I am kind of worried because there is a wait function in there and if multiple units cast this at the same time... it kind of overlaps so global is out of question though.
 
Level 29
Joined
Jul 29, 2007
Messages
5,174
IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) == true


And you should desperately change all those BJs into natives:
IsUnitAliveBJ
UnitDamageTargetBJ
AddSpecialEffectLocBJ
GetLastCreatedEffectBJ
GetBooleanAnd // put both conditions in the same function

Use coordinates instead of locations.

You leak a group in your random unit picking. Instead set a group variable to the units and then pick first/random unit from it (doesn't really matter which one, FirstOfGroup is faster).

Your condition function should be
JASS:
function Trig_Song_of_Chaos_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A07U'
endfunction

GetSpellAbilityUnit is a global, so don't EVER use it with waits. Use GetTriggerUnit which is a local.

local integer spelllevel = GetUnitAbilityLevel (caster, GetSpellAbilityId()

The main function only runs if the GetSpellAbilityId is 'A07U', so why run it again? Just change it to 'A07U'.
 
Level 4
Joined
Aug 12, 2004
Messages
76
Oh is native faster than BJs? Thank you.

IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) == true


And you should desperately change all those BJs into natives:
IsUnitAliveBJ
UnitDamageTargetBJ
AddSpecialEffectLocBJ
GetLastCreatedEffectBJ
GetBooleanAnd // put both conditions in the same function

Use coordinates instead of locations.

You leak a group in your random unit picking. Instead set a group variable to the units and then pick first/random unit from it (doesn't really matter which one, FirstOfGroup is faster).

Your condition function should be
JASS:
function Trig_Song_of_Chaos_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A07U'
endfunction

GetSpellAbilityUnit is a global, so don't EVER use it with waits. Use GetTriggerUnit which is a local.

local integer spelllevel = GetUnitAbilityLevel (caster, GetSpellAbilityId()

The main function only runs if the GetSpellAbilityId is 'A07U', so why run it again? Just change it to 'A07U'.

Is there no way to pass parameters in Condition (function xxxx) ?
 
Level 4
Joined
Aug 12, 2004
Messages
76
No, hence globals. What do you have against them anyways?

They can't stack.

Well, I just don't like using globals because I just like using the wait command a lot. Plus, if multiple units use this at once, then... yeah... globals don't work.
 
Status
Not open for further replies.
Top