• 🏆 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] Is this MUI?

Status
Not open for further replies.
Level 2
Joined
Jan 31, 2011
Messages
8
JASS:
function SS_heal takes nothing returns nothing
    call SetUnitLifeBJ(GetEnumUnit(), GetUnitStateSwap(UNIT_STATE_LIFE, GetEnumUnit()) - udg_healz)
    call AddSpecialEffectTargetUnitBJ( "overhead", GetEnumUnit(), "Abilities\\Spells\\Undead\\DeathPact\\DeathPactTarget.mdl" )
    endfunction

function SS_matching takes nothing returns boolean
    return (IsUnitEnemy( GetFilterUnit(), Player(0)) == true)
    endfunction
    
    function SS_matching2 takes nothing returns boolean
    return (IsUnitAliveBJ( GetFilterUnit()))
    endfunction
    
        function SS_matching3 takes nothing returns boolean
    return (GetBooleanAnd( SS_matching(), SS_matching2()))
    endfunction



function SS_Cond takes nothing returns boolean
  if (not (GetSpellAbilityId() == 'A000')) then
  return false
  else
  return true
  endif
endfunction

function SS takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local real aoe = 600.00
    local integer ALevel = GetUnitAbilityLevel(u,'A000')
    local integer unitingroup = CountUnitsInGroup(GetUnitsInRangeOfLocMatching( aoe, GetUnitLoc(u), Condition(function  SS_matching3)))
    local real damage = ((I2R(ALevel) * 10.00) * I2R(unitingroup))
    set udg_healz = damage
    call AddSpecialEffectTargetUnitBJ( "overhead", u, "Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl" )
    call ForGroupBJ( GetUnitsInRangeOfLocMatching( aoe, GetUnitLoc(u), Condition(function SS_matching3)), function SS_heal)
    call SetUnitLifeBJ( u, (GetUnitStateSwap(UNIT_STATE_LIFE, u) + udg_healz))
    endfunction

//===========================================================================
function InitTrig_SS takes nothing returns nothing
    set gg_trg_SS = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ(gg_trg_SS, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition( gg_trg_SS, Condition(function SS_Cond))
    call TriggerAddAction( gg_trg_SS, function SS )
endfunction

im sori for my impotence but i dont really know how to find out if my triggers are mui..Pls help me.
 
Level 2
Joined
Jan 31, 2011
Messages
8
Oh? 2 conditions can be merge??action and condition can be merge also?? hmm what do you mean about native counter parts? im sori but yesterday was my first day of using jass for my spells.
 
for example, SS_matching 3 can just be:
JASS:
function SS_matching3 takes nothing returns boolean
    return (IsUnitEnemy( GetFilterUnit(), Player(0)) and IsUnitType(GetFilterUnit(), UNIT_TYPE_DEAD))
endfunction

As for merging conditions and actions, basically, you put the actions inside the conditions part...

Those red functions are BJs which just call their native counterparts. So since ur using JASS, its a lot better to use the natives directly... You can view them on JNGP or on jasscraft...

this will still need lots of work since its basically just a converted GUI with some locals added...
 
Merging conditions and actions are as follows. In your initialization function (usually starts off with InitTrig_ as a function name [unless using vJass]), you simply add a condition as you normally would, except ignore adding an action, example:
JASS:
function InitTrig_Test takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerAddCondition(t, Condition(function Test_onCast)) // function Test_onCast is your condition function
    // however, since we are merging conditions and actions, this will be your function for both
endfunction

Then your function would basically follow this pattern:
JASS:
function onCast takes nothing returns boolean
    if <boolean condition> then // this is your condition check
        // for example, if GetSpellAbilityId() == 'A000' then
        // ... do your actions
    endif
    return false
endfunction

However, this is not really necessary if you are just learning JASS. In my opinion, just ignore this until your are comfortable with using JASS, since the difference is somewhat minor.

For now, I recommend that you look into fixing leaks and inlining the BJ functions.

For fixing leaks, any leak tutorial will do (check out our tutorial forum for great guides on that). For example, GetUnitsInRangeOfLocMatching creates a new group, and therefore you need to destroy it (or recycle it or whatever) just as you would in GUI. Some will tell you to use a global or recycle and whatnot, but that just complicates thing when learning, so just use the same process as GUI. Therefore, you would set the group to a local variable (or a global, whichever you choose) and then destroy it at the end of the function.

The next step is to inline BJ functions. They are mostly function wrappers that could be worked around easily. The BJ functions will all show up as red. (either in Jass NewGen or on this forum) To inline it, you just look at the function (open it up in Jass NewGen) and use what they use directly. Generally, if it is too difficult to inline, you can just leave it as it is, but otherwise you should inline it. (especially for those that have only one function)

For example:
JASS:
call SetUnitLifeBJ(GetEnumUnit(), GetUnitStateSwap(UNIT_STATE_LIFE, GetEnumUnit()) - udg_healz)
That line can be inlined to become:
JASS:
call SetUnitState(GetEnumUnit(), GetUnitState(GetEnumUnit(), UNIT_STATE_LIFE) - udg_healz)

Of course, some stuff can be optimized further, such as using GetWidgetLife and things along those lines, but you shouldn't worry too much about optimization just yet. It will grow on you, trust me. ;) For now, just practice on making spells and getting used to programming in JASS, and then it will become much much easier to move on from there.

EDIT: Adiktuz beat me to the post. :p

EDIT2: @Adiktuz, my mistake, ty fixed.
 
Last edited:
JASS:
call SetUnitLife(GetEnumUnit(), GetUnitState(GetEnumUnit(), UNIT_STATE_LIFE) - udg_healz)

does not exist and should be

JASS:
call SetWidgetLife(GetEnumUnit(), GetWidgetLife(GetEnumUnit()) - udg_healz)

or

JASS:
call SetUnitState(GetEnumUnit(), UNIT_STATE_LIFE, GetUnitState(GetEnumUnit(), UNIT_STATE_LIFE) - udg_healz)
 
Level 2
Joined
Jan 31, 2011
Messages
8
Yeah Thanks! you guys just made my day along with God haha ok ill just grow with it..for now just study harder in spell making..Love yah guys! +rep!
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
defs, all GUI triggers are converted to JASS if saved and it is ugly in structure, no wonder they are slow...

sample the ForGroupBJ or Pick every units in blahhh, the structure is like this...
JASS:
function ForGroupBJ takes group whichGroup, code callback returns nothing
    // If the user wants the group destroyed, remember that fact and clear
    // the flag, in case it is used again in the callback.
    local boolean wantDestroy = bj_wantDestroyGroup
    set bj_wantDestroyGroup = false

    call ForGroup(whichGroup, callback)

    // If the user wants the group destroyed, do so now.
    if (wantDestroy) then
        call DestroyGroup(whichGroup)
    endif
endfunction

that's why before we always use set bj_wantDestroyGroup = true

but instead a faster way is the native...
JASS:
native ForGroup takes group whichGroup, code callback returns nothing

and yes there are non-MUI things in jass just as Lender's statement, if you dont code it properly...
 
Lender said:
every scripts that uses globals and have timer(s) (or in worst situations waits...) are basically neither MUI nor MPI

What? Taking a look even at just the spells section will ensure you that this statement is false...

especially look at DoT systems and the likes, they use GLOBALS AND TIMERS...

@mckill - right now, FoG loops are faster than ForGroups
 
Level 6
Joined
Jun 16, 2007
Messages
235
First, combine the conditions and actions part into just conditions...
Second, replace those BJs with their native counterparts
Third, maybe replace function names and merge some of those SS_matching

Please don't listen to this person, he is an optimization zombie.
Optimization zombies believe in merging - of everything.

First of all: NEVER merge conditions and actions, it will make your code ugly and unreadable.

Second: NEVER replace BJs it is a waste of your time, better make some new code than fix things that don't need fixing.

Third: NEVER merge functions (I think you get my philosophy by now) Instead learn to use libraries and scopes (you will need NewGen for this).

=======
When you should optimize, merge stuff and replace BJs?
1. When you have a timer that runs on high frequency for example 0.025 seconds.
2. When you make unit_damage system
=======

Example of well coded open-source map(self commercial):
http://www.hiveworkshop.com/forums/map-development-202/6-aos-priest-vs-necro-207129/
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
what the hell is FoG?, for all I know FoG imo is FirstOfGroup and ForGroup ;P...

Second: NEVER replace BJs it is a waste of your time, better make some new code than fix things that don't need fixing.

100% disagree coz it depends on the situation...sample the DestroyEffectBJ which is this...
JASS:
function DestroyEffectBJ takes effect whichEffect returns nothing
    call DestroyEffect(whichEffect) // <<< call this directly oO
endfunction
 
Level 6
Joined
Jun 16, 2007
Messages
235
100% disagree coz it depends on the situation...sample the DestroyEffectBJ ...
Please don't use fixed examples, it is the same thing as lying.
When a BJ has more than one argument they are usually swapped in BJ and non-BJ or there is an extra defaut argument, so you have to look it up in the function list.
In total you will waste 1-10 seconds of your life every time you remove a BJ.
And there are a lot of BJs in jass and you have better things to do than waste your time on them - for example work on your triggers?

I will state this once more:
REMOVING BJs DOES NOT OPTIMIZE YOUR MAP.
Optimizing triggers that execute very often does.

All else is just a waste of time, I think that BJ-izm can be classified as obsessive compulsive behavior.
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
this is already offtopic...

it's not about optimizing but it's about silliness of what blizzard did, instead of
ONE, they did ONE, TWO...do you know how silly that is?...

many of us 'may' not know that libraries work a-like with BJ's coz the script is
there ready to use or it's already a preset thing, but frankly, the ovious
duplication of a function should be deprecated and be replaced with a
simple native...
 
Level 6
Joined
Jun 16, 2007
Messages
235
this is already offtopic...

it's not about optimizing but it's about silliness of what blizzard did, instead of
ONE, they did ONE, TWO...do you know how silly that is?...

The problem with you people is that you presume that you are smart and that professional programmers who made you a toy to play with are stupid.

The BJ functions exist for a reason, the programming technique is known as wrapping. Wrapper functions are useful for inserting hooks.
The problem is that blizzard did not export hook engine to jass but keeps it for themselves.
For example inserting a hook in functions for registering a chat event would have a great antihack use.
Or imagine that you can hook into certain BJ's so that they display debug messages to you in singleplayer - great way for testing.

About optimization: I already explained what it is and what it is not, go back and read more carefully.
 
Status
Not open for further replies.
Top