Hey, i've just started using the galaxy editor and I have a few galaxy coding questions. I have prior experience using VJass, Java, and some C so I mainly just need to know syntax.
1. How do I destroy an object I create via a struct (wipe the memory so I can use it again)
2. How do I get the handle ID of a unit?
3. How do I destroy a group
4. How do I declare libraries/classes (or whatever they are called in Java) so that I can encapsulate functions and variables together and declare them private.
1) You can't destroy it per se. You can just overwrite all it's content and re-use it. There is no dynamic creation/destruction.
2) You can get a unit's handle with a little trick:
The function UnitGetPropertyInt(unit u, int property_index, bool current) can return things like the unit's health or energy. But when you give it a property index of more than 24 (I think it was 24) then you instead get an integer which is unique for every unit. However, the integer is always a multiple of 64. So you get 0, 64, 128, 196, 256, etc etc.
3) The function is called UnitGroupClear( unitgroup )
4) Just like Jass, Galaxy does not have classes, nor real libraries. There also is no real way to declare vars or functions private.
Only through VJass this was possible in Wc3. It's the same in Starcraft 2. There already is something like VJass (http://www.sc2mod.com/board/index.php?page=Board&boardID=16) but it's far less convenient to use and it suffers from Galaxy's shortcomings.
1) You can't destroy it per se. You can just overwrite all it's content and re-use it. There is no dynamic creation/destruction.
Thanks ^-^
2) You can get a unit's handle with a little trick:
The function UnitGetPropertyInt(unit u, int property_index, bool current) can return things like the unit's health or energy. But when you give it a property index of more than 24 (I think it was 24) then you instead get an integer which is unique for every unit. However, the integer is always a multiple of 64. So you get 0, 64, 128, 196, 256, etc etc.
I'll try that ty. I can't believe they didn't put in a native to get the handle ID of a unit but whatever I guess (that's blizz for you)
3) The function is called UnitGroupClear( unitgroup )
Does that completely destroy the group or just clear all units from it? I was wondering how to destroy a group object variable entirely so all the memory is freed up.
4) Just like Jass, Galaxy does not have classes, nor real libraries. There also is no real way to declare vars or functions private.
Only through VJass this was possible in Wc3. It's the same in Starcraft 2. There already is something like VJass (http://www.sc2mod.com/board/index.php?page=Board&boardID=16) but it's far less convenient to use and it suffers from Galaxy's shortcomings.
Alright i'll just keep everything global then I guess.
1) You can't destroy it per se. You can just overwrite all it's content and re-use it. There is no dynamic creation/destruction.
Alternatively.. You the data could be stored in data tables, which can be destroyed. It's possible to assign data to unique keys that are based on the current game time for a specific player. After which, just create a code that can search the data table for the key you are looking for. But I find this method to be rather cumbersome. I prefer struct recycling like what s3rius suggested. You would just use a "pointer" that resets to 0 everytime it hits the struct limit. So once it hits the end it starts writing from the beginning again. Similar to how a ring buffer works.
Quote:
3) The function is called UnitGroupClear( unitgroup )
Does that completely destroy the group or just clear all units from it? I was wondering how to destroy a group object variable entirely so all the memory is freed up.
Eh? I thought galaxy had garbage collection that handles this on a function/trigger basis?
Does that completely destroy the group or just clear all units from it? I was wondering how to destroy a group object variable entirely so all the memory is freed up.
SC2 utilizes a garbage collector, which removes objects, which are no longer used. This applies to unit groups as well. Local groups are deleted, when they are no longer referenced to. Global groups are re-used at some point usually, which either overwrites the current group with a new one, making the old one garbage collected, or emptys the current group and re-fills it, which makes destruction obsolete.
Still, I would like an explicit destroy function.
Note that this might not be 100% accurate information, this is based on my own understanding ;)
Create a trigger reacting to the timer expired event. There is no other possibility I know of.
However, if you are referring to the Jass way of making high frequency spells by starting a timer and attaching all needed values to it; you can use waits + local variables for most applications instead. Unlike in Jass, a wait in SC2 is just as accurate as a timer, so using wait over timers is not a no-go anymore.
"Create a trigger reacting to the timer expired event. There is no other possibility I know of."
Thats unfortunate, thanks for the info. on wait timers though
________
Can anyone possibly tell me why this code isn't working, i'm just trying to play around with galaxy a bit and I seem to be doing something wrong. I'm fairly certain my triggers/events are written wrong somehow.
Also btw does anybody know about a syntax highlighter add-on I can DL b/c the galaxy one is buggy as hell (atleast for me). It's half-highlighting some keywords and isn't highlighting others at all. And because the colors chosen don't constrast at all with the text, I can barely see what little highlighting it does do.
You could use Notepad+ + or Beier's script editor (3rd party tools section); there is no add-on for the galaxy editor I know of.
For your code, print some more text messages to see, if the initialization works (did you start the functions somewhere or put their correct names in a custom script initializer line?) and if the trigger reactions work.
€ does this compile at all? Triggers need to use a function returning boolean with 2 boolean parameters. So instead of
I was actually trying to do something along the same line as you.. But since there is no function to attach a function to a trigger.. I am disappoint. Here's how I worked around it though.
Create a trigger with a timed event (0.0625s), then save the trigger into the global data table with a string based on the triggering players game time.
Code a function that searches the data table for the trigger, then retrieves this string used to store it.
When the trigger fires, call the function. You now have a string that should be unique for every instance of the trigger.
You can either use this key to pull out other values that you store in the data table, or use it to store a 'pointer' to a struct at which all the spell cast information is stored. Such as the unit that casted it, the cast point, the target etc.
€ does this compile at all? Triggers need to use a function returning boolean with 2 boolean parameters. So instead of
void TestFunction()
you use
bool TestFunction (bool a, bool b)
____________
It compiles. You mean functions that are called by a trigger event use the 2 booleans? What do the two boolean parameters represent and what happens if I return true/false?
A trigger function needs to return boolean, and it needs 2 parameters: bool TestConditions and bool RunActions.
The first one checks the conditions if true, false skips them. The second one runs the actions if true, false skips again.
The return returns false, if the conditions were not met, and returns true, if they were met or skipped (independent of the actions being executed).
Note that these are automatically used by gui triggers converted to galaxy code; code looks kinda like this:
So the parameters are handled within the function, but they are not essential for the trigger to work. If you do not need them, you can just ignore them; however the function for a trigger response still needs to have 2 boolean parameters and to return boolean.
The parameters and the return value are needed for the functions to evaluate a trigger's conditions or run a trigger (evaluate basically runs the trigger with TestConditions true and RunActions false and checks the return, the run trigger function can skip the conditions, which sets the TestConditions parameter accordingly. So if you need those functions to work properly, make sure to add their functionality as described).
Well, its not exactly a timer, its a periodic event that calls the trigger. I believe they aren't the same?
To be honest with you I can't think of an advantage over your method. Maybe we could collaborate and do a test to see which is more efficient? Though that would involve some design of experiment (DOE.. Which I absolutely suck at. We need to come up with some kind of unbiased realistic scenario to compare against.
The main difference I see between our methods, is that in the one I chose to use, there isn't a trigger that's just sitting in memory doing nothing while it's waiting. Whether or not this has a noticeable effect on performance, I don't know. But lets just say there are 1000 instances of our spell being cast within a short timeframe.
On a memory/processing level, 1000 idle functions might not be very efficient as they could potentially lock up the memory, preventing/delaying new actions that may be taking place from processing. In which case, 1000 triggers that are destroyed whenever they are not used would be a more logical solution. I'm not trying to put your method down or anything, this is just in theory. There's always a chance I could be understanding this wrongly.
No offense taken, dont worry ;) If we can prove, "your" way is the better one I'd be the first to spam the forum with these news.
Well, an argument against it might be, that we have a trigger event triggering every .0625 all the time, regardless of a spell instance currently being in use or not. Also for few spell instances running like 2 or 3 trigger events, followed by a loop containing waits might still be more efficient than 0.0625 events triggered per second (assuming triggering 1 event takes more time than 1 wait + 1 loop step)
Could be just like in wc3, running 1 timer + loop through all spell instances vs starting 1 timer per spell instance. For most applications, there would be no noticeable difference, but low instance count favors 1 timer per instance, while high instance count favors 1 timer for all instances.
Hey, i've just started using the galaxy editor and I have a few galaxy coding questions. I have prior experience using VJass, Java, and some C so I mainly just need to know syntax.
1. How do I destroy an object I create via a struct (wipe the memory so I can use it again)
2. How do I get the handle ID of a unit?
3. How do I destroy a group
4. How do I declare libraries/classes (or whatever they are called in Java) so that I can encapsulate functions and variables together and declare them private.
Any help would be appreciated ^-^
1) You can't destroy it per se. You can just overwrite all it's content and re-use it. There is no dynamic creation/destruction.
2) You can get a unit's handle with a little trick:
The function UnitGetPropertyInt(unit u, int property_index, bool current) can return things like the unit's health or energy. But when you give it a property index of more than 24 (I think it was 24) then you instead get an integer which is unique for every unit. However, the integer is always a multiple of 64. So you get 0, 64, 128, 196, 256, etc etc.
3) The function is called UnitGroupClear( unitgroup )
4) Just like Jass, Galaxy does not have classes, nor real libraries. There also is no real way to declare vars or functions private.
Only through VJass this was possible in Wc3. It's the same in Starcraft 2. There already is something like VJass (http://www.sc2mod.com/board/index.php?page=Board&boardID=16) but it's far less convenient to use and it suffers from Galaxy's shortcomings.
1) You can't destroy it per se. You can just overwrite all it's content and re-use it. There is no dynamic creation/destruction.
Thanks ^-^
2) You can get a unit's handle with a little trick: The function UnitGetPropertyInt(unit u, int property_index, bool current) can return things like the unit's health or energy. But when you give it a property index of more than 24 (I think it was 24) then you instead get an integer which is unique for every unit. However, the integer is always a multiple of 64. So you get 0, 64, 128, 196, 256, etc etc.
I'll try that ty. I can't believe they didn't put in a native to get the handle ID of a unit but whatever I guess (that's blizz for you)
3) The function is called UnitGroupClear( unitgroup )
Does that completely destroy the group or just clear all units from it? I was wondering how to destroy a group object variable entirely so all the memory is freed up.
4) Just like Jass, Galaxy does not have classes, nor real libraries. There also is no real way to declare vars or functions private. Only through VJass this was possible in Wc3. It's the same in Starcraft 2. There already is something like VJass (http://www.sc2mod.com/board/index.php?page=Board&boardID=16) but it's far less convenient to use and it suffers from Galaxy's shortcomings.
Alright i'll just keep everything global then I guess.
Thanks for all your help ^-^
Alternatively.. You the data could be stored in data tables, which can be destroyed. It's possible to assign data to unique keys that are based on the current game time for a specific player. After which, just create a code that can search the data table for the key you are looking for. But I find this method to be rather cumbersome. I prefer struct recycling like what s3rius suggested. You would just use a "pointer" that resets to 0 everytime it hits the struct limit. So once it hits the end it starts writing from the beginning again. Similar to how a ring buffer works.
Eh? I thought galaxy had garbage collection that handles this on a function/trigger basis?
SC2 utilizes a garbage collector, which removes objects, which are no longer used. This applies to unit groups as well. Local groups are deleted, when they are no longer referenced to. Global groups are re-used at some point usually, which either overwrites the current group with a new one, making the old one garbage collected, or emptys the current group and re-fills it, which makes destruction obsolete.
Still, I would like an explicit destroy function.
Note that this might not be 100% accurate information, this is based on my own understanding ;)
Thanks for all your replies ^-^
@MTops: Go
Please upload that into the wiki, there is a big novelty for it.
They've added them in some patch, haven't they? I remember the handle ID being something with 20 last time I tried.
Anyway, added them to my personal files :3 thanks.
It's on the wiki: http://wiki.sc2mapster.com/galaxy/triggers/presets/unit-property-get/
Another question if you don't mind
How do I start a timer and pass a function for it to run through when the timer is finished?
i.e. something like:
TimerStart(WhichTimer?, HowLong?, WhichFunction?)
Theres gotta be one i'm sure
Create a trigger reacting to the timer expired event. There is no other possibility I know of.
However, if you are referring to the Jass way of making high frequency spells by starting a timer and attaching all needed values to it; you can use waits + local variables for most applications instead. Unlike in Jass, a wait in SC2 is just as accurate as a timer, so using wait over timers is not a no-go anymore.
"Create a trigger reacting to the timer expired event. There is no other possibility I know of."
Thats unfortunate, thanks for the info. on wait timers though ________
Can anyone possibly tell me why this code isn't working, i'm just trying to play around with galaxy a bit and I seem to be doing something wrong. I'm fairly certain my triggers/events are written wrong somehow.
Any help would be appreciated ^-^
Also btw does anybody know about a syntax highlighter add-on I can DL b/c the galaxy one is buggy as hell (atleast for me). It's half-highlighting some keywords and isn't highlighting others at all. And because the colors chosen don't constrast at all with the text, I can barely see what little highlighting it does do.
You could use Notepad+ + or Beier's script editor (3rd party tools section); there is no add-on for the galaxy editor I know of.
For your code, print some more text messages to see, if the initialization works (did you start the functions somewhere or put their correct names in a custom script initializer line?) and if the trigger reactions work.
€ does this compile at all? Triggers need to use a function returning boolean with 2 boolean parameters. So instead of
you use
@MTops: Go
I was referring to the literals actually, not the constants. The wiki link doesn't have the literal values.
@Raven0: Go
I was actually trying to do something along the same line as you.. But since there is no function to attach a function to a trigger.. I am disappoint. Here's how I worked around it though.
€ does this compile at all? Triggers need to use a function returning boolean with 2 boolean parameters. So instead of
void TestFunction() you use
bool TestFunction (bool a, bool b)
____________
It compiles. You mean functions that are called by a trigger event use the 2 booleans? What do the two boolean parameters represent and what happens if I return true/false?
Thanks for your help so far
@FuzzYD: Go
Whats the advantage in having a timer over a loop + wait + local variables?
@Raven0: Go
A trigger function needs to return boolean, and it needs 2 parameters: bool TestConditions and bool RunActions.
The first one checks the conditions if true, false skips them. The second one runs the actions if true, false skips again.
The return returns false, if the conditions were not met, and returns true, if they were met or skipped (independent of the actions being executed).
Note that these are automatically used by gui triggers converted to galaxy code; code looks kinda like this:
So the parameters are handled within the function, but they are not essential for the trigger to work. If you do not need them, you can just ignore them; however the function for a trigger response still needs to have 2 boolean parameters and to return boolean.
The parameters and the return value are needed for the functions to evaluate a trigger's conditions or run a trigger (evaluate basically runs the trigger with TestConditions true and RunActions false and checks the return, the run trigger function can skip the conditions, which sets the TestConditions parameter accordingly. So if you need those functions to work properly, make sure to add their functionality as described).
@Kueken531: Go
Well, its not exactly a timer, its a periodic event that calls the trigger. I believe they aren't the same?
To be honest with you I can't think of an advantage over your method. Maybe we could collaborate and do a test to see which is more efficient? Though that would involve some design of experiment (DOE.. Which I absolutely suck at. We need to come up with some kind of unbiased realistic scenario to compare against.
The main difference I see between our methods, is that in the one I chose to use, there isn't a trigger that's just sitting in memory doing nothing while it's waiting. Whether or not this has a noticeable effect on performance, I don't know. But lets just say there are 1000 instances of our spell being cast within a short timeframe.
On a memory/processing level, 1000 idle functions might not be very efficient as they could potentially lock up the memory, preventing/delaying new actions that may be taking place from processing. In which case, 1000 triggers that are destroyed whenever they are not used would be a more logical solution. I'm not trying to put your method down or anything, this is just in theory. There's always a chance I could be understanding this wrongly.
@FuzzYD: Go
No offense taken, dont worry ;) If we can prove, "your" way is the better one I'd be the first to spam the forum with these news.
Well, an argument against it might be, that we have a trigger event triggering every .0625 all the time, regardless of a spell instance currently being in use or not. Also for few spell instances running like 2 or 3 trigger events, followed by a loop containing waits might still be more efficient than 0.0625 events triggered per second (assuming triggering 1 event takes more time than 1 wait + 1 loop step)
Could be just like in wc3, running 1 timer + loop through all spell instances vs starting 1 timer per spell instance. For most applications, there would be no noticeable difference, but low instance count favors 1 timer per instance, while high instance count favors 1 timer for all instances.
Do we have benchmark natives available?
@Kueken531
I tend to just write my own trigger conditions using an if/then at the beginning of the function so I guess I won't need to use the parameters at all.
What exactly happens if I return false vs. true? Nothing (besides interrupting the code obviously)?
and thanks again for all your help ^-^