| 02-09-2004, 01:52 AM | #1 |
How does this JASS function work? If you put call CreateTrigger( joe) then what is it doing? Is it making that function its own trigger? I need help to understand this. |
| 02-09-2004, 02:00 AM | #2 |
Click Here <--- Click There |
| 02-09-2004, 02:42 AM | #3 |
whoops, I realized I was being dumb, but I still don't understand. Okay, so if I have a function that goes something like this. Code:
function my_Func takes nothing returns nothing
local trigger joe = CreateTrigger()
endfunction |
| 02-09-2004, 04:34 AM | #4 |
Jass is procedural programming with objects. (You can just read that as a contradiction or a confused programming language.) Now jass complicates the matter with what i'll latter explain but lets just ignore this for now. And Now Object Oriented Programming 101 What we have to explain briefly is the concept of pointers: When you declare (ie. local trigger t) you just create a reference identifier which points to nothings. If you try doing anything trigger related with this trigger it obviously won't work, because its trying to do something with nothing. (You can't push buttons on nothing.) The variable is just a pointer. Its not the actual object itself, it just happens to be a variable dedicated to storing the address of this type of object. Thus you use this thing called an instiator statement (in this case CreateTrigger()) to create an object of that type and return the pointer. However, just calling CreateTrigger is trivial, as it will just pass the pointer to nothing. Thus you will never be able to access this trigger directly. This is ussually the fault of memory leaks we suffer in worldedit because groups and locations and the likes are made on the spot and are non-referenced. So to properly handle this we do local trigger t=CreateTrigger(). Jass calls all its objects handles. However, not in jass is a handle. The other types of variables are called primitives. In jass there are 3 primitives: integers,reals, and booleans. These variables actually contain the content of their type and do not require instatation. Strings in Jass are NOT handles, but are not primitives. They are a unique type they are an object in the traditional sense but they do not extend handle nor are they true primitives (i'll explain the test for primitives later). ... int x=7; System.out.println(x); ChangeInt(x); System.out.println(x); } void ChangeInt(int x){ x=x+1; } This code should display 7 and 7. Because primitives just pass thier content not thier pointer. So while x in the function ChangeInt was 8, it did not effect the variable that passed it that value. Now the main concern you'll have later is something called mutability. Lets look at a simple function in java. Let say we have an object called a counter a wrapper class of integer with a method called inc which will increment it and a propper to string method that will display its integer content. ... Counter ct=new Counter(7); System.out.println(ct); ChangeCt(ct); System.out.println(ct); } void ChangeCt(Counter ct){ ct.inc() } Now this on the other hand will display 7 and 8. This is because a counter is a mutable object. Since you passed the function not the counter itself, but the pointer to a counter object it used the pointer to call the inc method on the counter object. Now lets look at this other example this time using strings in java. (which are true objects) ... String s="7"; System.out,println(s); Changestr(s); System.out.println(s); } void ChangeStr(String s){ s="8" } This will display 7 and 7. This is because the only way to change the content of a string is to create a new string object. Since s is merely a pointer it just now is pointing to a new object in the changestr function, but in the calling function it is still pointing to the old one. Now war3 stores all types as 4 bytes. Generally I like thinking of it is as Everythings an integer, except reals. But the first statement is more correct. How we came to this conclusion is the return type bug.(Blessing). function h2i takes handle h returns integer return h return 0 endfunction Generally that function up that can convert anything to an integer. You'll need to specify explicitly for the other types. (Real, boolean, string). Reals when converted to integers show thier 4 bytes of data, booleans convert to 0 for false and ones for true, and strings point to some other object stack. As all handles are in the 10,000+ range while strings are in the range of 0-255 and will recycle if the string literal has the same content. [For the TL:DR crowd] Alright enough confusing you. As you guessed it creates a trigger with no actions, because local trigger joe is an uninitialized object which causes threads to crash if you don't point something to it. |
| 02-09-2004, 11:15 PM | #5 |
Thank you for an intelligent reply weaaddar. After DoCa posted, i decided to look at other peoples scripts and kind of made sense of it all. Here is what I understand now. Code:
function CreateTriggerBoom takes nothing returns nothing
local trigger Boom = CreateTrigger()
call TriggerAddAction( Boom, function Boom )
endfunction
funciton Boom takes unit whichUnit returns nothing
call ExplodeUnitBJ( whichUnit )
endfunction
function CauseBoom takes nothing returns nothing
call TriggerExecute( Boom )
endfunctionNow with the proper event, this would explode a unit right? Oh, I had a question, I figured that the acutal name of the function really didn't matter, but how does WC decide which function to run next? Which one does it run first? Does there have to be one name Trig_Joe_Actions for it to run the trigger at all? |
| 02-10-2004, 02:51 PM | #6 |
Well just because that last reply sound confused, I feel like having to talk here, I won't explain a lot of weird stuff like weaaddar since I learned all my programming thanks to all the days I spent in front of a computer since I was 12: Triggers in JASS are the same as triggers in gui, they have conditions, actions and events, the thing is that the editor converts the gui trigger into JASS and uses predefined (by blizzard) names for everything. The functions you posted will do nothing, in fact they will just give you a lot of compile errors or even crash the editor when saving. As of your question on what determines what function is executed first, I will have to explain a lot: A trigger needs either an event or an action to be worthy, triggers with no events are often used with Run Trigger, and triggers with no actions are used to detect events, (this is something I won't elaborate more) Conditions aren't really necessary unless you want to add a condition to the thing that detects the events... To answer your last question, A function will not be executed unless you call it when necessary, to explain better I will give a example: We have this trigger in gui: Code:
Explode footmanEvents:
A unit enters explodearea <gen>
Conditions
Unit type of triggering unit equal to Footman
Actions
Explode (triggering unit)Trigger AThe editor will convert it into: Code:
function Trig_Explode_footman_Conditions takes nothing returns boolean
return GetUnitTypeId(GetTriggerUnit()) == 'hfoo'
endfunction
function Trig_Explode_footman_Actions takes nothing returns nothing
call ExplodeUnitBJ( GetTriggerUnit())
endfunction
//========================================
function Init_Trig_Explode_footman takes nothing returns nothing
set gg_trg_Explode_footman = CreateTrigger()
call RegisterEnterRectSimple( gg_trg_Explode_footman, gg_rct_explodearea)
call TriggerAddAction( gg_trg_Explode_footman, function Trig_Explode_footman_Actions)
call TriggerAddCondition( gg_trg_Explode_footman, Condition(function Trig_Explode_footman_Conditions))
endfunctionI said a function needs to be called to be executed. To make the Trig_Explode_footman_Actions function to be executed just at the moment a unit enters to a rect( region in normal editor) called explodearea I need a trigger that executes that function after that event. Badly enough to have a trigger I first need to create it, and to create the trigger I use the Init_Trig_Explode_footman function. But I need something to call that function, when saving the editor will make a "hidden" script for the map (You can see the script with file\export map script) that script contains all the custom script section, then all the triggers converted to custom text and finnally a function that is automatically executed by the game at map initialization, that function is like Code:
function InitTriggers takes nothing returns nothing
call ...
call Init_Trig_Explode_footman()
call ...
endfunctionI don't remember how exactly that function is but the thing is that it will automatically execute all the Init_ functions for all of the triggers so the triggers will be initialized. So it will execute: Code:
function Init_Trig_Explode_footman takes nothing returns nothing
set gg_trg_Explode_footman = CreateTrigger()
call RegisterEnterRectSimple( gg_trg_Explode_footman, gg_rct_explodearea)
call TriggerAddAction( gg_trg_Explode_footman, function Trig_Explode_footman_Actions)
call TriggerAddCondition( gg_trg_Explode_footman, Condition(function Trig_Explode_footman_Conditions))
endfunctionThat function will first save a newly created trigger into gg_trg_Explode_footman , a generated trigger global variable, then it will register the unit enters explodearea event to that trigger. Then will register the function Trig_Explode_footman_Actions as the actions for that trigger (so that function will be executed after the event happens) and will register the function Trig_Explode_footman_Conditions as a condition to execute the action. |
| 02-10-2004, 07:03 PM | #7 |
Vex, most of my knowledge comes from programming. I just happen to be a OOP loving kid so I know my fundamentals of pass by reference and pass by variable objects. And now more information: Vex is correct, When war3 runs you map it executes two functions. One is called The main function not unlike your main function in C/C++/Java. This is the one which instiates all triggers etc. Config is the second function which generates for all the pregame information (like how many players specificied race etc) Your function you provided Narwanza would not work at all for numerous reasons. First Jass only knows the code above it so you can't register the action above the event. And second to be an action or condition function it must have the take nothing return nothing signature. Also Functions can not share the name of variables. While vexorians example is good if your not creating one on the fly. But if you are making one inside a different trigger you would go: funciton kaboom takes nothing returns nothing call ExplodeUnitBJ( udg_myunit ) endfunction function CreateTriggerBoom takes nothing returns nothing local trigger Boom = CreateTrigger() call TriggerAddAction( Boom, function kaboom ) endfunction function Irunatinit takes nothing returns nothing call CreateTriggerBoom() endfunction function CauseBoom takes nothing returns nothing set udg_myunit=unittodie() call TriggerExecute( Boom ) endfunction Generally this is not a great example. AN important note about the initalization thread (the main function) is like any other trigger it can die and waits do not work in it so you generally want to move anytyhing extensive to run away at map init., |
| 02-10-2004, 11:59 PM | #8 |
That is basically what I had earlier except the initilization trigger you put in. I meant to put that in my map. Thanks for helping me guys. The main thing I really didn't know about CreateTrigger() was that you had to add a function as the actions, and if you needed conditions and events. I didn't know how to do this until I read some funcitons at the Vault. Then it all started making sense to me. You have helped clear up a couple of questions I had that i didn't ask though, so thank you for your intelligent replies. I know that my previous funcitons made no sense because they weren't layed out in a practical application, but I think they would have worked if I had put them all in the right triggers. Anyways, thx. |
| 02-11-2004, 12:32 AM | #9 |
As we said earlier they wouldn't of worked because of the signature error. you must have it as a takes nothing returns nothing function. That and theres no defination of which unit... |
| 02-11-2004, 02:25 AM | #10 |
I get ya now weaaddar. It makes sense, thx for the help. I realize that takes unit whichUnit won't work because of the action signature needs to be takes nothing returns nothing, so therefore I would have to use globals. Thx. |
