Saturday, April 21, 2012

How could I slim this trigger down? (jass)

hello i've got this trigger i think i could slim down using one of those kind of functions which you declare at the start of the map, for example if you have a lot of messages to display you could just call that function and then the message instead of writing the whole function. I think you guys know what i mean...

Anyways, that's what I would like to do with this beast:


Code:
function Trig_Init_Func001C takes nothing returns boolean
if ( not ( GetPlayerSlotState(Player(0)) == PLAYER_SLOT_STATE_PLAYING ) ) then
return false
endif
return true
endfunction

function Trig_Init_Func002C takes nothing returns boolean
if ( not ( GetPlayerSlotState(Player(1)) == PLAYER_SLOT_STATE_PLAYING ) ) then
return false
endif
return true
endfunction

function Trig_Init_Func003C takes nothing returns boolean
if ( not ( GetPlayerSlotState(Player(2)) == PLAYER_SLOT_STATE_PLAYING ) ) then
return false
endif
return true
endfunction

function Trig_Init_Func004C takes nothing returns boolean
if ( not ( GetPlayerSlotState(Player(3)) == PLAYER_SLOT_STATE_PLAYING ) ) then
return false
endif
return true
endfunction

function Trig_Init_Func005C takes nothing returns boolean
if ( not ( GetPlayerSlotState(Player(4)) == PLAYER_SLOT_STATE_PLAYING ) ) then
return false
endif
return true
endfunction

function Trig_Init_Func006C takes nothing returns boolean
if ( not ( GetPlayerSlotState(Player(5)) == PLAYER_SLOT_STATE_PLAYING ) ) then
return false
endif
return true
endfunction

function Trig_Init_Func007C takes nothing returns boolean
if ( not ( GetPlayerSlotState(Player(6)) == PLAYER_SLOT_STATE_PLAYING ) ) then
return false
endif
return true
endfunction

function Trig_Init_Func008C takes nothing returns boolean
if ( not ( GetPlayerSlotState(Player(7)) == PLAYER_SLOT_STATE_PLAYING ) ) then
return false
endif
return true
endfunction

function Trig_Init_Actions takes nothing returns nothing
if ( Trig_Init_Func001C() ) then
call SetPlayerStateBJ( Player(0), PLAYER_STATE_RESOURCE_GOLD, 100 )
call CreateNUnitsAtLoc( 1, 'Hpal', Player(0), GetRectCenter(gg_rct_Red), bj_UNIT_FACING )
else
call DoNothing( )
endif
if ( Trig_Init_Func002C() ) then
call SetPlayerStateBJ( Player(1), PLAYER_STATE_RESOURCE_GOLD, 100 )
call CreateNUnitsAtLoc( 1, 'Hpal', Player(1), GetRectCenter(gg_rct_Blue), bj_UNIT_FACING )
else
call DoNothing( )
endif
if ( Trig_Init_Func003C() ) then
call SetPlayerStateBJ( Player(2), PLAYER_STATE_RESOURCE_GOLD, 100 )
else
call CreateNUnitsAtLoc( 1, 'Hpal', Player(2), GetRectCenter(gg_rct_Teal), bj_UNIT_FACING )
call DoNothing( )
endif
if ( Trig_Init_Func004C() ) then
call SetPlayerStateBJ( Player(3), PLAYER_STATE_RESOURCE_GOLD, 100 )
call CreateNUnitsAtLoc( 1, 'Hpal', Player(3), GetRectCenter(gg_rct_Purple), bj_UNIT_FACING )
else
call DoNothing( )
endif
if ( Trig_Init_Func005C() ) then
call SetPlayerStateBJ( Player(4), PLAYER_STATE_RESOURCE_GOLD, 100 )
call CreateNUnitsAtLoc( 1, 'Hpal', Player(4), GetRectCenter(gg_rct_Yellow), bj_UNIT_FACING )
else
call DoNothing( )
endif
if ( Trig_Init_Func006C() ) then
call SetPlayerStateBJ( Player(5), PLAYER_STATE_RESOURCE_GOLD, 100 )
call CreateNUnitsAtLoc( 1, 'Hpal', Player(5), GetRectCenter(gg_rct_Orange), bj_UNIT_FACING )
else
call DoNothing( )
endif
if ( Trig_Init_Func007C() ) then
call SetPlayerStateBJ( Player(6), PLAYER_STATE_RESOURCE_GOLD, 100 )
call CreateNUnitsAtLoc( 1, 'Hpal', Player(6), GetRectCenter(gg_rct_Green), bj_UNIT_FACING )
else
call DoNothing( )
endif
if ( Trig_Init_Func008C() ) then
call SetPlayerStateBJ( Player(7), PLAYER_STATE_RESOURCE_GOLD, 100 )
call CreateNUnitsAtLoc( 1, 'Hpal', Player(7), GetRectCenter(gg_rct_Pink), bj_UNIT_FACING )
else
call DoNothing( )
endif
endfunction

//===========================================================================
function InitTrig_Init takes nothing returns nothing
set gg_trg_Init = CreateTrigger( )
call TriggerAddAction( gg_trg_Init, function Trig_Init_Actions )
endfunction

i know it's probably not THAT huge but I think i could learn something from this.|||You need a For Loop and those regions placed into an array. After that, it should be pretty simple.|||Quote:






View Post

You need a For Loop and those regions placed into an array. After that, it should be pretty simple.




okay ^^ thanks|||Code:
function Trig_FireTrucks_Trigger_Actions takes nothing returns nothing
local integer i = 0
local integer iend = 7
loop
exitwhen i > iend
if ( GetPlayerSlotState(ConvertedPlayer(i)) == PLAYER_SLOT_STATE_PLAYING ) then
call SetPlayerStateBJ( ConvertedPlayer(i), PLAYER_STATE_RESOURCE_GOLD, 100 )
call CreateNUnitsAtLoc( 1, 'Hpal', ConvertedPlayer(i), udg_RegionPoint[i], bj_UNIT_FACING )
else
endif
set i = i + 1
endloop
endfunction

Here's an example of how your trigger probably should look, since I wasn't specific. You'd need a point variable array where each point has been assigned (center of region for the player) at map initialization using the JASS enumeration of the player (i.e. Player 1 = 0). As you can see, I collapsed the player codes all down to one line each using a For Loop and collapsed the condition down to a single in-line condition, since I wanted to switch the loop over to a local variable instead of the For Loop integer global.

If you are going to convert from GUI, make good GUI first (e.g. use For Loops and variable arrays for player-related stuff). Also, your original code was leaking points for the region references, so switching to a global variable array for points will make it easy to clean those up if you aren't using center of the players' regions again.

As a very side note, you can make the function part of this code even a little tighter if you are an obsessed code-monkey. For example, the functions that end with BJ (example: SetPlayerStateBJ) usually just call the native function, which is identical except the arguments are arranged in a less straight-forward manner. By using the non-BJ form your code makes fewer function calls. It's really not worth the effort, but code-monkeys are obsessed and obsession usually interferes with effort exerted vs. results. There's also a native function that CreateNUnits calls, which creates each unit one at a time, for example. You should probable work your way into that level of obsession slowly, though.|||ok, thanks again.


Quote:




so switching to a global variable array for points will make it easy to clean those up if you aren't using center of the players' regions again.




hmm, kk but i wonder why globals are easier to clean up / nullify than locals. would be nice if you or someone else could tell me. also, from what i've learned 0.00 / 0 nullifies a real / integer, right? if so, why is 0 easier for a computer to keep in mind than for example 3?

edit: i tried that out, but I stumbled upon trouble imediatley (<- spelling?)... im not sure how to declare a region array variable. I tried searching for it on google but didnt find it. Im thinking something like
Code:
set udg_region array [0]

but im not sure whether to put 0 or 7 in the "[x]"(min or max?) also, should there be a " = y" after the
Code:
set udg_region array [x]

? and if so, what should it say instead of y? Im guessing 0?

edit2: okay, i came this far on my own:


Code:
    local integer i = 0
set udg_regions[i] = gg_rct_0

i renamed the regions to 0,1,2,3,4,5,6 and 7. i was foolish enough to think that i could just use
Code:
gg_rct_i

and that would give all the regions. But, no. and that's why i need some moar help :P for short: how to declare that region array variable thing, and what how come (following is from your code)
Code:
 udg_RegionPointt[i]

works. I mean, how did you get the
Code:
i

in there?

edit3: the trigger atm:


Code:
function Trig_Init2_Actions takes nothing returns nothing
local integer i = 0
set udg_regions[i] = GetRectCenter(gg_rct_0)
loop
exitwhen i > 7
if ( GetPlayerSlotState(ConvertedPlayer(i)) == PLAYER_SLOT_STATE_PLAYING ) then
call SetPlayerStateBJ( ConvertedPlayer(i), PLAYER_STATE_RESOURCE_GOLD, 100 )
call CreateNUnitsAtLoc( 1, 'Hpal', ConvertedPlayer(i), udg_regions[i], bj_UNIT_FACING )
call DisplayTimedTextToForce(GetPlayersAll(), 2, "you have gained 100 gold!" ) //<- just 4 testing
else
endif
set i = i + 1
endloop
endfunction



//===========================================================================
function InitTrig_init2 takes nothing returns nothing
set gg_trg_init2 = CreateTrigger( )
call TriggerAddAction( gg_trg_init2, function Trig_Init2_Actions )
endfunction

if i disable / enable this one, the editor finds no problems at all, but when I run the map, i get a FATAL ERROR. oh well|||Quote:






View Post

but i wonder why globals are easier to clean up / nullify than locals. would be nice if you or someone else could tell me.




They aren't. You weren't making any attempt to clean leaks in the initial trigger - my point was just that if you made them globals (instead of just letting them leak) they would be easier to clean.


Quote:






View Post

from what i've learned 0.00 / 0 nullifies a real / integer, right? if so, why is 0 easier for a computer to keep in mind than for example 3?




Whoever told you that doesn't know what they are talking about. Integers and reals don't leak and therefore they don't need to be "nullified". I don't get why it is still such a mystery to people what leaks are and why things leak. Leaks are created by referencing objects that haven't been created yet. Since integers and reals aren't objects, they are numbers, there is nothing being created - they are just values being set. Your question exemplifies the point exactly - why would it be any easier for a computer to remember 0 or 3? It wouldn't be.


Quote:






View Post

im not sure how to declare a region array variable.




How about going into the variable editor and creating the variable and clicking on array... like every other time you have ever made a global variable?


Quote:






View Post

im not sure whether to put 0 or 7 in the "[x]"(min or max?)




You don't need to set the initial size of region or point arrays. There are very few variable types that require you to set their size at initialization.

If you had read my post a little more closely, you would have realized that I am recommending point variable arrays (not regions) and that somewhere else (i.e. not in this trigger, but at map initialization) you should fill the value of these points with 'center of region' values.


Quote:






View Post

how did you get the
Code:
i

in there?




I typed it in there. In this case "i" is the same as IntegerA in a For Loop (GUI), except I replaced it with a local variable that I declared.

You could make this entire trigger without JASS - and I think you should try that before you try the JASS version, since you seem to be having so much trouble with the fundamentals (like creating a global variable) and basic argument types - for example, you are trying to create a unit at a region instead of a point, which is probably why you got a fatal.

One of the primary reasons they made the GUI, instead of just forcing all map-makers to learn the underlying language, is because it keeps track of the argument types for you and it's harder to screw things up that way. I'm not sure if you are just trying to learn JASS to learn it or if there is something you think you might accomplish with JASS that you wouldn't be able to with GUI. Just because someone thinks JASS is cooler doesn't mean you should be using it - you should use whatever you are most comfortable with, unless there is something you feel you just can't do with GUI. Sometimes that's the case, but it's fairly rare.|||Quote:




Whoever told you that doesn't know what they are talking about. Integers and reals don't leak and therefore they don't need to be "nullified". I don't get why it is still such a mystery to people what leaks are and why things leak. Leaks are created by referencing objects that haven't been created yet. Since integers and reals aren't objects, they are numbers, there is nothing being created - they are just values being set. Your question exemplifies the point exactly - why would it be any easier for a computer to remember 0 or 3? It wouldn't be.




ok. thanks for clearing that up :) sry 4 the joke, couldnt resist.


Quote:




You don't need to set the initial size of region or point arrays. There are very few variable types that require you to set their size at initialization.

If you had read my post a little more closely, you would have realized that I am recommending point variable arrays (not regions) and that somewhere else (i.e. not in this trigger, but at map initialization) you should fill the value of these points with 'center of region' values.




yes, i know, sry. I noticed that later. my bad.. (3 minutes of thinking later)... oh! i get it! im not using a variable to declare the points, i should use a variable to referance the points. So i type
Code:
set udg_regions[0] = GetRectCenter(<region0>)


Code:
set udg_regions//just the name of the variable, this is indeed a point variable[1] = GetRectCenter(<region1>)

and so on... and then when i want to referance these points I type
Code:
call CreateNUnitsAtLoc( 1, 'Hpal', ConvertedPlayer(i), udg_RegionPoint[i], bj_UNIT_FACING )

...I hope for both our sanity's sake i've got it right now.


Quote:




One of the primary reasons they made the GUI, instead of just forcing all map-makers to learn the underlying language, is because it keeps track of the argument types for you and it's harder to screw things up that way. I'm not sure if you are just trying to learn JASS to learn it or if there is something you think you might accomplish with JASS that you wouldn't be able to with GUI. Just because someone thinks JASS is cooler doesn't mean you should be using it - you should use whatever you are most comfortable with, unless there is something you feel you just can't do with GUI. Sometimes that's the case, but it's fairly rare.




for a number of reasons....

1 for future mapmaking - i might need it later if not now

2 i figure not forcing the program to translate GUI triggers to jass (not sure if they have to, if im wrong please correct me) would reduce lag and make the map smoother overall?

3 i'm kind of a perfectionist and want my maps to be as well done as possible

4 i'm curious and fascinated.

edit: solved the fatal error.|||Quote:






View Post

i figure not forcing the program to translate GUI triggers to jass (not sure if they have to, if im wrong please correct me) would reduce lag and make the map smoother overall?




When you hit "save" on any map in GUI, the map compiles that code into JASS. Unless you mean you don't want to wait as long while the map saves after you hit the save button, then you aren't forcing anything to convert.

In other words, all maps "play" in JASS, regardless of how they are originally encoded. The letters GUI stand for guided user interface - they are just that - a user interface for JASS. This concept that programming in GUI somehow makes a map slower is based on programming nerds who are running hundreds or thousands of actions in a second and watching to see how the two differ in terms of fractions of seconds. The only people who should care about those sorts of things are people with crap computers who probably can barely run WC3 (and even then, it's debatable).

Using JASS to write the code is slightly cleaner (fewer functions are called to perform the same actions) if you do it well - but writing something in JASS doesn't inherently make it better or faster. Code monkeys care, but the people playing your map won't notice any difference in almost every case. And since you should be making maps for people to play rather than as abstract works of code, it only matters to you how you make something work (and that it actually works how you intend it to). For a lot of people, who are used to programming languages, writing stuff in JASS is more natural or faster - but that doesn't make it better.

I'm not trying to discourage you - I think it is useful to know JASS (obviously). I just sometimes wonder why people would struggle with it so much that they become discouraged when it usually doesn't provide an equivalent measure of utility for them.


Quote:






View Post

i'm kind of a perfectionist and want my maps to be as well done as possible




Trust me when I say that it is more important for your map to be "done" than "well-done". The number of maps that code monkeys (or anyone for that matter) start but fail to complete is massive. You put yourself into a much better position if you "complete" a map and then revise the coding efficiency than you ever would trying to make the coding perfect first and try to complete a map. Some of the best maps are made by people with no understanding of JASS. Like I said before, good design is hard - good coding is (relatively) easy.|||ok, chunk ill definately absorb that and see where it goes. im not promising anything though! :P

anyways, i think i've definately learned something from this thread|||lol I just read my posts in here and it's a wonder you even come close to understanding what i mean. I'm not making myself clear at all xD

No comments:

Post a Comment