HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Orginization Help

08-15-2009, 12:21 AM#1
Cheezeman
Hello again fellow Jassers.

It's kinda late so my grammar sucks. Sorry for the inconvinience.

I'm using a filter which checks which targets can be affected by a spell.
However, it's a bit messy.
I mean look at it:
Collapse JASS:
    private function AllowedTargets takes unit caster, unit target returns boolean
        return (IsUnitType(target, UNIT_TYPE_MECHANICAL) == false) and IsUnitEnemy( target, GetOwningPlayer( caster ) ) and ( GetWidgetLife( target ) > 0.405 ) and ( IsUnitType( target, UNIT_TYPE_STRUCTURE ) == false) and (IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE) == false)
        //Don't worry about the code, it works fine.
    endfunction

If this was for a map it wouldn't be a problem.
However, this is for a spell I've released, and in it I aim at User-friendlyness, not efficiency (basically I want even the most noobish Jasser to be able to use it in an easy way).
But this is simply too unorganized for a user to manipulate without casuing errors.

In GUI you can do it like this
Trigger:
Untitled Trigger 001
Events
Conditions
Collapse Actions
Collapse If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Collapse If - Conditions
Collapse And - All (Conditions) are true
Collapse Conditions
(target is A structure) Equal to False
(target is Magic Immune) Equal to False
-------- Etc --------
Then - Actions
Else - Actions

But the Jass script of the above just looks like shit.
If there was some way to do this or something similar in Jass I'd most gladly use it, since it's alot easier to manipulate.

Help most appriciated

All yours
- Cheezeman
08-15-2009, 12:39 AM#2
Opossum
Your GUI trigger might look pretty now but it's one hell of an abomination when converted to Jass.

You can do it like this in Jass:
Collapse JASS:
    private function AllowedTargets takes unit caster, unit target returns boolean
        if not IsUnitType(target, UNIT_TYPE_MECHANICAL) then
            if IsUnitEnemy( target, GetOwningPlayer( caster ) ) then 
                if GetWidgetLife( target ) > 0.405  then 
                    if not IsUnitType( target, UNIT_TYPE_STRUCTURE ) then
                        return not IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE)
                    endif
                endif
            endif
        endif
        return false
    endfunction
Iirc it isn't even slower than using ands. If you really care about speed though you should probably make sure the most unlikely condition comes first so the whole function is exited as soon as possible.
08-15-2009, 01:10 AM#3
Anitarf
You could do something like:
Collapse JASS:
function cond takes unit caster, unit target returns boolean
    local boolean b = true
    set b = b and (IsUnitType(target, UNIT_TYPE_MECHANICAL) == false) // Must be non-mechanical.
    set b = b and IsUnitEnemy( target, GetOwningPlayer( caster ) ) // Must be an enemy.
    set b = b and ( GetWidgetLife( target ) > 0.405 ) // Must be alive.
    set b = b and ( IsUnitType( target, UNIT_TYPE_STRUCTURE ) == false) // Must not be a structure.
    set b = b and (IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE) == false) // Must not be magic immune.
    return b
endfunction
I also sometimes use xedamage for targeting options, in cases when the spell already uses xedamage.
08-15-2009, 11:47 AM#4
Cheezeman
A very good solution Anitarf. Would've never thought about something like that myself.

Quote:
Your GUI trigger might look pretty now but it's one hell of an abomination when converted to Jass.
Quote:
But the Jass script of the above just looks like shit.
If there was some way to do this or something similar in Jass I'd most gladly use it, since it's alot easier to manipulate.
08-15-2009, 12:58 PM#5
Viikuna-
I find this a nice solution too:

Collapse JASS:
function AllowedTargets takes unit caster, unit target returns boolean
        return not IsUnitType     (target, UNIT_TYPE_MECHANICAL)       /*  
       */  and     IsUnitEnemy    (target, GetOwningPlayer( caster))   /*    
       */  and     GetWidgetLife  (target) > 0.405                     /* 
       */  and not IsUnitType     (target, UNIT_TYPE_STRUCTURE)        /* 
       */  and not IsUnitType     (target, UNIT_TYPE_MAGIC_IMMUNE)   
endfunction
08-15-2009, 01:33 PM#6
Anitarf
Indeed, that is pretty sweet.
08-15-2009, 03:11 PM#7
Cheezeman
Is the */ a vJass feature?
Not that it matters, just curious.

Edit: Forgot to say that yours is even sweeter than anitarf's cause it's more efficient.

Edit: Does this look easy enough for a noob to config?
Collapse JASS:
    private function AllowedTargets takes unit caster, unit target returns boolean
        return /*
        
        //==================================================           
        //These are the targets the spell will affect.                      //The target...
        */ GetWidgetLife( target ) > 0.405                          and /*  //- must be dead
        */ IsUnitEnemy( target, GetOwningPlayer( caster ) )         and /*  //- must be an enemy of caster
        */ IsUnitType(target, UNIT_TYPE_MECHANICAL) == false        and /*  //- mustn't be mechanical
        */ IsUnitType( target, UNIT_TYPE_STRUCTURE ) == false       and /*  //- mustn't be a structure
        */ IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE) == false      and /*  //- mustn't be magic immune
        //To add more, simply copy a line and add your condition
        //==================================================
        
        */ true
    endfunction

Edit: I just realized... with this you can add comments in the middle of a line.
Pure awesome
08-15-2009, 04:57 PM#8
fX_
Quote:
Originally Posted by Viikuna-
I find this a nice solution too:

Collapse JASS:
function AllowedTargets takes unit caster, unit target returns boolean
        return not IsUnitType     (target, UNIT_TYPE_MECHANICAL)       /*  
       */  and     IsUnitEnemy    (target, GetOwningPlayer( caster))   /*    
       */  and     GetWidgetLife  (target) > 0.405                     /* 
       */  and not IsUnitType     (target, UNIT_TYPE_STRUCTURE)        /* 
       */  and not IsUnitType     (target, UNIT_TYPE_MAGIC_IMMUNE)   
endfunction
what
...
a witch
08-15-2009, 07:07 PM#9
Anitarf
You mean the target "must be alive", not dead?

Also, I like the "not" keyword better than "==false".
08-15-2009, 11:26 PM#10
Cheezeman
1: Yes, I do
2: That's personal preference

Edit: New code (if anyone's interested), with minor aestetics changes
Collapse JASS:
    private function AllowedTargets takes unit caster, unit target returns boolean
        return /*
        
        //==================================================           
        //These are the targets the spell will affect.                      //The target...
        */ GetWidgetLife( target ) > 0.405                          and /*  //- must be alive
        */ IsUnitEnemy( target, GetOwningPlayer( caster ) )         and /*  //- must be an enemy of caster
        */ IsUnitType( target, UNIT_TYPE_STRUCTURE ) == false       and /*  //- mustn't be a structure
        */ IsUnitType( target, UNIT_TYPE_MECHANICAL ) == false      and /*  //- mustn't be mechanical
        */ IsUnitType( target, UNIT_TYPE_MAGIC_IMMUNE ) == false    and /*  //- mustn't be magic immune
        //To add more, simply copy a line, add it to the block
        //and enter your condition.
        //==================================================
        
        */ true
    endfunction
08-16-2009, 12:37 AM#11
thehellman
Wow, this thread has helped me a lot too, I use to have really long 1 liners.

I have a few questions though.

What is /* and */, in most programming languages its to open and end comment blocks, but it isn't doing the same or is it?

Also, can condition take parameters?

Right now for timer-spell effect that create groups I do this for the filter.

function cond takes nothing returns nothing
local timer t= GetExpiredTimer()
local unit u = loadunithandle(.., .., .. )
IsUnitEnemy(filterunit(), u )
endfunction

boolexpr filter = Condition(function cond)

Sorry for rough code, don't have WE open.
08-16-2009, 01:14 AM#12
Anitarf
Quote:
Originally Posted by thehellman
What is /* and */, in most programming languages its to open and end comment blocks, but it isn't doing the same or is it?
It is doing the same.

Quote:
Also, can condition take parameters?

Right now for timer-spell effect that create groups I do this for the filter.

function cond takes nothing returns nothing
local timer t= GetExpiredTimer()
local unit u = loadunithandle(.., .., .. )
IsUnitEnemy(filterunit(), u )
endfunction

boolexpr filter = Condition(function cond)
Well, what are we talking about, conditions or timer callbacks? Those are two different things. Neither of them can take arguments, though, you need to attach any data you may need in the function to the timer that runs it. That's why we have TimerUtils.
08-16-2009, 01:16 AM#13
thehellman
Just want to make sure I'm right, you attach a struct to the timer right?
08-16-2009, 08:25 AM#14
Pyrogasm
Quote:
Originally Posted by thehellman
Just want to make sure I'm right, you attach a struct to the timer right?
Yep.
08-16-2009, 10:22 AM#15
Flame_Phoenix
Quote:
It is doing the same.
TESH doesn't seem to recognize this, mmmm