HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Sorry about being noob, but what are...

07-04-2008, 01:52 AM#1
Burning Rose
So I've looked around and found quite a few simple JASS tutorials, and quite a few advanced ones. However, I can't seem to find many intermediate ones. I'm good enough to clean up basic leaks and make simple (While not the most streamlined, they don't leak like crazy) spells. However, whenever I try to look at other JASS scripts or tutorials I get confused out of my mind.

So, Pretty Much, can anyone either explain to me or point me to an explanation for:
  • Dynamic or non-Dynamic Triggers?
  • Scopes?
  • Libraries?
  • Structs?
  • TextMacros (I know what a Macro is in WoW... but that doesn't seem to helpful here)?
  • the difference between just calling a function and using executefunc or triggerexecute (I think those are the functions)?

BTW: I understand that explaining any, much less all of this, could be quite the pain, and I completely understand if no one really feels like it. It is a lot after all, and It certainly seems noobish as far as I can tell. But, I can't seem to find enough information on these things on my own :(.
07-04-2008, 02:15 AM#2
Rising_Dusk
The JASS Helper Manual will answer all of your vJass questions with examples and everything.

A function call keeps it within the same thread, whereas using ExecuteFunc() created a new thread for that function. Additionally, TriggerExecute runs a trigger which may or may not have actions on it. TriggerEvaluate checks the conditions of a trigger. (Generally used to run code variables via non-leaking conditions)
07-04-2008, 02:56 AM#3
Burning Rose
Oh, I get the ExecuteFunc thing now, thanks.

I tried looking through the Manual and constantly felt like I must be missing something, and couldn't understand most of it :(.

EDIT: Hmm, I guess looking at it on a different day helped. I've been looking through scopes and libraries the past hour. Does this mean that instead of having to use H2I and Gamecache to attach variables to a timer, I can just use a Private Global in a scope? As in, the whole spell would be in a Scope, with the Initial function as a public, and then call that function on the trigger? Or are there ways to put an entire trigger into a scope or something like that? Although wait, would that be MUI? :X Maybe I'm thinking of Structs...
07-04-2008, 03:58 AM#4
Rising_Dusk
Quote:
Originally Posted by Burning Rose
Does this mean that instead of having to use H2I and Gamecache to attach variables to a timer, I can just use a Private Global in a scope
Not quite, but you can use structs for such attachment. All of the same rules apply to vJass as do to Jass, just new interface options are open to you so that you can organize your things in new and more intricate ways. (That's what vJass ultimately allows)

Scopes and libraries are just good ways to make your spells and systems respectively. They allow such keywords as private and public, so that you avert conflicts and overall they protect you from yourself. (Also makes typing the function and variable names easier)
07-04-2008, 05:55 AM#5
chobibo
Dynamic triggers are triggers ( do not mistake them from the triggers in GUI, they are the event handlers ) that are created and destroyed at runtime. For example, Damage Detection Library implements dynamic array usage. Non-dynamic or static arrays are the ones that are created and not destroyed intentionally, and are used throughout the game, it can detect generic events which make them useful.

Dynamic arrays-Created and destroyed at runtime
Static arrays-triggers used throughout the game

Scopes isolate a piece of code from other parts of the code, like how local variables isolate variables and only work inside the functions where they are declared. public scopes are accessible and private aren't.
07-04-2008, 04:27 PM#6
Burning Rose
So would using Structs instead of attaching things avoid the "Nulling a Timer removes it's attachments" bug I've heard about? And it would also be MUI, right?

Oh and Chobibo, thanks with the Dynamic Arrays things. (Also, nice sig. I played Legend of Mana so many times...)
07-04-2008, 06:33 PM#7
Rising_Dusk
Quote:
Originally Posted by Burning Rose
So would using Structs instead of attaching things avoid the "Nulling a Timer removes it's attachments" bug I've heard about? And it would also be MUI, right?
Structs are not an attachment method, they are an organization method. By using structs, H2I, and StoreInteger, you can reliably and safely work in cache without ever worrying about it causing strange bugs based on handle stack corruptions. It could be MUI or not depending on how you code it, obviously.

If you recycle timers, you never have to worry about nullifying them anyways. I wrote a tutorial in the jass section once that elaborates on that.
07-04-2008, 07:00 PM#8
chobibo
CSData 15.2 (storage system) + CSSafety 15.2( timers ) + Structs, that's what I recommend if you want to make MUI spells. Of course there are other storage systems out there, you may choose what you like to use. Just note that you can't use CSData for units for multiple spells, use gamecache instead. Remember, timers-CSData, units-gamecache. If used together with structs, CSSafety and avoidance of handle destruction, gamecache is stable.
07-04-2008, 07:25 PM#9
Anitarf
It seems like CSSafety along with Table should be everything anyone would ever need.

Edit: CSSafety could use a better name.
07-05-2008, 08:37 AM#10
Burning Rose
Ah, well cool, I already have caster system in my map (With CSCache and CSSafety, obviously). Thanks all :D, I feel like I can get farther in JASS now!
07-05-2008, 09:34 AM#11
Ammorth
Quick clarification on using structs for spells.

instead of doing:
Collapse JASS:
function SpellMain takes nothing returns nothing
    local timer t = CreateTimer()
    call AttachInt(t, "lvl", GetSpellLevel())
    call AttachUnit(t, "caster", GetTriggerUnit())
    call AttachGroup(t, "affected", CreateGroup())
    ...
endfunction

and then getting them back in the callback function (ill spare you the code), you can do:

Collapse JASS:
struct SpellData
    integer level
    unit caster
    group affected
endstruct

function SpellMain takes nothing returns nothing
    local timer t = CreateTimer()
    local SpellData d = SpellData.create() // creates a unique struct of type SpellData
    set d.level = GetSpellLevel() // set the values of SpellData
    set d.caster = GetTriggerUnit()
    set d.group = CreateGroup()
    ...
    call AttachInt(t, "data", d) // attach the struct to the timer
// only 1 attach instead of numerous attached and no type casting from integer to handle when getting the data back
endfunction

function CallBack
    local SpellData d = GetAttachedInt(GetExpiredTimer(), "data")
    call DoStuffWithLevel(d.level)
    call DoStuffWithCaster(d.caster)
    call DoStuffWithGroup(d.affected)
    ...
    call AttachInt(GetExpiredTimer(), "data", 0) // null the attach
    call d.destroy() // destroy the struct since you are done.
endfunction

With many variables being passed, this is far more efficient than having 15 gamecache calls an iteration.
07-05-2008, 11:21 AM#12
Anitarf
Ammoroth's example is also a good example of why it's smart to use create and onDestroy methods for such structs, he forgot to clean up the unit group before he destroyed the struct which is something you are less likely to forget if you use an onDestroy method.
07-05-2008, 08:14 PM#13
Ammorth
Its also an example to not write code when you're half asleep. Although looking back, I didn't do half bad on it.
07-05-2008, 08:15 PM#14
Anitarf
Quote:
Originally Posted by Ammorth
Its also an example to not write code when you're half asleep. Although looking back, I didn't do half bad on it.
Nope, you didn't, I've seen far worse. ;)
07-05-2008, 11:26 PM#15
Burning Rose
Ah, cool then.