Discussion New Language - Discussion

SerraAvenger

Cuz I can
Reaction score
234
[LJASS]"%s was killed by %p"%(GetPlayerName(a), GetPlayerName(b))[/LJASS]

[LJASS]// Readability! Yay![/LJASS]
[LJASS]GetPlayerName(a) + "was killed by" + GetPlayerName(b)[/LJASS]

what he MEANT was this:

[LJASS]"%p was killed by %p" % [a, b][/LJASS]

[LJASS]GetPlayerName(a) + "was killed by" + GetPlayerName(b)[/LJASS]


What I'ld love to see:

making all normal types use the same interface as "structs" or vv, so that

Code:
unit u = event.get_trigger_unit()
u.set_state( UNIT_STATE_HP, 40 )
 

Lyerae

I keep popping up on this site from time to time.
Reaction score
105
But what if [ljass]exitwhen[/ljass] is already defined? I'm pretty sure you can't have multiple.
 

SerraAvenger

Cuz I can
Reaction score
234
But what if [ljass]exitwhen[/ljass] is already defined? I'm pretty sure you can't have multiple.

You can have multiple. exitwhen [blubb] is a simple
[LJASS]if ( blubb ) { break; }[/LJASS]

Now continue cannot work as [LJASS]exitwhen false[/LJASS]; Instead it'll have to ignore the rest of the loop. Such stuff is incredibly hard to compile in certain situations and, if compiled into JASS, should run quite slow.

Note this [Abstract]:
JASS:
loop{
 exitwhen 4==6
 break
 continue
}

// would have to become something like this:

loop
 exitwhen exitor_a
 loop
   // exitwhen 4==6
   set exitor_a = 4==6
   exitwhen exitor_a
   // break
   set exitor_a = true   
   exitwhen exitor_a
   // continue
   exitwhen true
 endloop
endloop


yay!

[real life example]

JASS:
i = 0
loop{
 exitwhen i>=6
 if ( var[ i ] == null ) {
   break 
 }
 else {
   i += 1
   continue
 }
 i += 1
}

// would have to become something like this:

local integer i = 0
loop
 exitwhen exitor_a
 loop
   set exitor_a = i>=6
   exitwhen exitor_a
   if var[ i ] == null then
     set exitor_a = true
     exitwhen exitor_a
   else
     set i = i + 1
     exitwhen true
   endif
   set i = i + 1
 endloop
endloop


EDIT:
ofc for loops and stuff would have to work like this:
JASS:
for (i=0; i<=6; i+= 1) {
 [blubb]
}
//...
local integer i = 0
loop 
  set exitor_a = i<=6
  exitwhen exitor_a

  loop
     [blubb]
     exitwhen true
  endloop
  set i = i + 1
endloop


EDIT:
exitor_a ... exitor_Z are for different levels of loops. Should be locals, but I THINK they can be global too.
 

SerraAvenger

Cuz I can
Reaction score
234
Well that's all quite confusing. :/

You need a mechanism to ignore the rest of the loop and RESTART [with the next element, if available]

So, in fact, we need something to EXIT THE LOOP and RESTART IT.
We do so by having 2 loops;
The inner loop, our "traditional loop", which allows us to exit, and the outer loop, which allows us to restart.
JASS:
loop
 loop
  STUFF_A
  exitwhen true
  STUFF_B
 endloop
endloop

In this loop, STUFF_A will be eternally repeated, STUFF_B will be ignored.
Now if we want to actually exit the loop, we want to exit both the inner AND the outer loop.
To know when we actually want to quit both loops, we need a local boolean variable - exitor_a.

JASS:
loop
 loop
  STUFF_A
  exitwhen true
  STUFF_B
 endloop
 exitwhen exitor_a // exit when I want to exit the loop
endloop


Now a simple
JASS:
loop
 exitwhen true
endloop

(aka [ljass]loop; break; endloop;[/ljass)
must be turned into a
JASS:
loop
  loop
    // break
    set exitor_a = true // store that we want to leave both loops
    exitwhen exitor_a // leave innerloop if the condition is met
    // endbreak
  endloop
  exitwhen exitor_a // leave the outer loop if the condition is met
endloop


For an [ljass]exitwhen [blubb][/ljass] it would, of course, become a [ljass]set exitor_a = [blubb][/ljass]
That way, both loops will be quit when exitor_a or, in other words, the exitwhen condition holds true.

For the "for" loop structure, we want the "continue" to go to the next element; hence the increment must happen within the outer loop - or at the very top of the inner loop. Since letting it happen at the TOP would change the traditional meaning of the "for" keyword [i=0 -> 0...n, not i=0 -> 1...n], that's not a good idea. So we need to let it happen at the end of the outer loop.
This also means that, in order to increment, we have to exit the inner loop - that's why there is an "exitwhen true" at the end of the inner loop.

JASS:
loop 
 // exit INSTANTLY when the exit condition is met
  set exitor_a = i<=6
  exitwhen exitor_a

  loop
     // user generated code ...

     exitwhen true // leave the inner loop to increment
  endloop
  exitwhen exitor_a // exit in case of a break statement or another exitwhen [stuff]
  set i = i + 1 // increment
endloop


Only that way can the functionality of a "continue" keyword be assured. Thats a wonderful thing, true, but it is hard to actually use.


What I'd love to see: Variables as arguments [using a hashtable]
Makes code much slower. Great to use.
JASS:
nothing ShowVar( * #test ) { 
  BJDebugMsg( R2S( test.value ) ) // using R2S on test.value assures us that test is a real variable
}
//...
    * lol = 5.0 // setting it to 5 shows that its a real
    ShowVar( #lol ) // as above, # tells us we give it the variable instead of the value
//...


->

JASS:
function ShowVar takes integer test returns nothing
 call BJDebugMsg( R2S( LoadReal( Lyerae_GAME_TABLE, 0, test ) ) ) 
endfunction

//...
    integer lol = 1335 // some unique number for this variable
    SaveReal( Lyerae_GAME_TABLE, 0, lol, 5.0 )
    call ShowVar( lol )
//...


EDIT:
Arrays could make use of hashtables 2 key thing :D
 

Strilanc

Veteran Scripter
Reaction score
42
Just going to chime in with a suggestion: handlers.

Manually setting up triggers is tedious. I want to be able to write something like this:

JASS:

function OnDeath(unit victim, unit killer) handles UnitDeath
    ...
endfunction


Which would translate into an init function to create a trigger with a unit death event and an action pointing to a function which calls OnDeath with the appropriate arguments.
 

tooltiperror

Super Moderator
Reaction score
231
^lazy, more like this, this will at least keep the flow.
JASS:
 // Interesting idea.

 handler UnitDeath // Start a Handling Block
     <Event ID> // Add in the Event ID for A Unit Dies
 endhandler // End it

 function examples takes handler UnitDeath returns nothing // Just a way to
                    // keep the flow up.
     return
 endfunction
 

SerraAvenger

Cuz I can
Reaction score
234
^lazy, more like this, this will at least keep the flow.
JASS:
 // Interesting idea.

 handler UnitDeath // Start a Handling Block
     <Event ID> // Add in the Event ID for A Unit Dies
 endhandler // End it

 function examples takes handler UnitDeath returns nothing // Just a way to
                    // keep the flow up.
     return
 endfunction

nonsense! It doesn't take a "handler", especially not like that...

Strilancs syntax is much more in the spirit of JASS/vJASS/Zinc...

"unit victim, unit killer"
should rather be
"unit victim = GetTriggerUnit(), unit killer = GetKillingUnit()"
Or even
"* victim = GetTriggerUnit(), * killer = GetKillingUnit()"
 

Executor

I see you
Reaction score
57
I'd love a language like this:

JASS:
lib stuff needs chat

    pawn    = null      // no type? yea, null tells the compiler that pawn is a handle
                        // and as pawn is set to a unit in the initializer the compiler
                        // knows that it's a unit var
    e       = null
    p       = Player(0) // is not constant, therefore will be added determined in a global initializer
    
    class Base          // struct Base
        r = 0           
        method Init     // works like the optional onInit method of vJass
            .r = 5*5*5  // set .r = 5*5*5 
    
    class Data(Base)    // struct Data extends Base
        method Init
            BJDebugMsg(R2S(.r))
            BJDebugMsg("%v + 5 = %v"/(1,6))     // => "1 + 5 = 6" the %v gets replaced by the values
                                                // in the brackets
    
    pickfunc killEm     // pickfunc => function killEm + killEm__Cond = Condition( function killEm )
                        // in PickUnitsInRange(....,killEm) automatically the already created condition
                        // will be used. You could also just use a func killEm but here the condition
                        // has to be created every call again
        u = GetFilterUnit()     // local unit u = GetFilterUnit()
        CreateEffect(GetUnitX(u),GetUnitY(u),"someString")  // DestroyEffect(AddSpecialEffect(...))
        KillUnit(u)

    public func doSomething(unit u):null    // everything is private except you add a "public"
                                            // (unit u) => takes unit u
                                            // (...):null => returns nothing
                                            // (...):nothing is the same
        x = GetUnitX(u)
        y = GetUnitY(u)
        RemoveUnit(u)
        PickUnitsInRange(x,y,300, killEm)   // call EnumUnitsInRange(...., killEm__Cond)
        if e != null
            RemoveEffect(e)
        e = CreatePermanentEffect(x,y,"someString") // set e = AddSpecialEffect(...)

    func Init // as always optional, but may not be introduces by "initializer Init" in the head
        pawn = CreateUnit(p,'hpea',0,0,270)
        
// ===================

scope doStuff
        
    func Init 
        doSomething(pawn)
        
// ====================
 

GetTriggerUnit-

DogEntrepreneur
Reaction score
129
Here's mine since everyone gives their syntax idea :D.

JASS:
public class Demonstration {

    public constant integer VALUE_25 = 25;
    // Can be accessed inside of the class, VALUE_25, and outside of the class, Demonstration.VALUE_25 using class reference. It's static.
    private constant integer VALUE_25 = 25;
    // Can be accessed only inside of the class. It's static.

    public integer Value_25;
    // Can be accessed inside of the class, Value_25, and outside of the class,   d.Value_25 (d being a class instance) using a class instance. It's dynamic.
    private integer Value_25
    // Can be accessed only inside of the class, It's dynamic

    // Save for functions & Methods

    and keyword: &&
    or keyword: ||

    public static void nameOfTheVoid() {
    }

    private boolean nameOfTheBoolean() {
        return false;
    }

// functions are accessed the same way as globals.

}
 

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
no type? yea, null tells the compiler that pawn is a handle

strings can also be set to null.

and as pawn is set to a unit in the initializer the compiler knows that it's a unit var

Why not just put the unit keyword behind it so that it's readable for other people? Python uses no types because it allows 'types' to easily be used just like other 'types'.

If you really want no types, you would have to make [ljass]call BJDebugMsg(pawn)[/ljass] work just like [ljass]call BJDebugMsg(GetUnitName(pawn))[/ljass], for every single type. Unfortunately, some things cannot be represented as a string.

JASS:
BJDebugMsg("%v + 5 = %v"/(1,6))     // => "1 + 5 = 6" the %v gets replaced by the values in the brackets

This is then completely useless if you can't reuse a value multiple times by referring to it as a variable. It makes more sense to inline everything.

JASS:
    pickfunc killEm     // pickfunc => function killEm + killEm__Cond = Condition( function killEm )
                        // in PickUnitsInRange(....,killEm) automatically the already created condition
                        // will be used. You could also just use a func killEm but here the condition
                        // has to be created every call again

...what?

JASS:
        CreateEffect(GetUnitX(u),GetUnitY(u),"someString")  // DestroyEffect(AddSpecialEffect(...))

This is a misleading name, plus it would add BJ-like functions. It would make more sense to alias "CreateEffect(*)" with "DestroyEffect(AddSpecialEffect(*))"

The misleading name could cause problems who don't understand the inner workings. Some effects don't have a death animation, and so they are never shown.

I personally still like the idea of using this syntax:

JASS:
public class Test {

    initializer {
        BJDebugMsg("class Test initialized")
    }

}


for the initializer. An initializer will never take, or return anything. This syntax will also separate it from actual methods/functions.
 

SerraAvenger

Cuz I can
Reaction score
234
I'd love a language like this:
>Indentation
I programmed python for two years and I know how nasty indentation is when you want to maintain your code -.-
While stuff like {} might be hard to type on most standard european keyboards, we might just use <> or () and it would be easier to maintain and to read.
Of course, you have to add two keystrokes per structure, but my.

>:null == :nothing
making null be converted to nothing seems pointless to me. We could always just omit the whole thing and not add any confusion oO

> pickfunc
A good idea. Using "pickfunc" though is a little bit... Strange. No need to craft new keywords... Using
Code:
filter killEm {
}
condition killEm {
}
Should be fine.
> PickUnits[...]
What for? Just for supporting your "pickfunc"-renaming-scheme? Apart from that, it just adds to confusion and makes it harder for oldschool jassers to adapt.

PS: Your naming conventions are aweful oO I hope you don't use them when you code for real =D
[LJASS]e = null[/LJASS] ... Yeah! e=null! -.-
I'm still for
* someEffect = null
Since that allows us to distinguish between declaration and a simple assignment. I think it also makes it much easier to parse...
* could as well be ?, var, ., :, -, # or whatever :D
JASS:
- userData
* userData
? userData
: userData
var userData
- userData
# userData

Well, you decide what looks best to you. * should actually not be used since it is much better used in stuff like that:
JASS:
unit Teststuff( unit *lol ){  // passing lol as a variable
  BJDebugMsg( lol.value.to_s ) // getting lol&#039;s value and converting it to string
}


Did I already say I dream of being able to use standard types as LL(Lyerae's Language) objects? It might impact my dream of not declaring types though. Kinda have to choose =D

It _might_ be cool to have something like this:
JASS:
class testclass {
 static integer count
 integer id
}

integer testclass.get_id ( testclass this ) { 
  return id
}

integer testclass.get_count ( ) { 
  return count
}

void onInit () {
  testclass tester =  testclass.new()
  BJDebugMsg( tester.get_id.to_s )
  BJDebugMsg( testclass.count.to_s )
}

perhaps even

JASS:
integer get_id ( testclass this ) { 
  return id
}

integer testclass.get_count ( ) { 
  return count
}

but well... allowing JASS native types to work as LL objects is a shitload of work for a nice, coherent style - we might as well change perspective and do this:

JASS:
integer GetTestClassId ( testclass this ) { 
  return id // using this makes sure it tries to address this.id
}

integer GetTestClassCount( ) { 
  return testclass.count
}

there are so many ways... g2g2sleep :D

EDIT: 2nd Darths statements. Want to answer his question:
Why not just put the unit keyword behind it so that it's readable for other people?
Because you might want to change during iterations because you find out stuff works better as widget than as unit/you want to use reals instead of integers/....
As long as its just one variable, thats all fine. But once you start to build a system around it, phew...
 

Executor

I see you
Reaction score
57
Well these were just some ideas. I didn't really brood over everything i meantioned :)

> strings can also be set to null.

Yea, but my idea of interpreting to determine the type would still work. Well but I think declaring the type would really be better (to read and processtime).

>If you really want no types, you would have to make call BJDebugMsg(pawn) work just like call BJDebugMsg(GetUnitName(pawn)), for every single type. Unfortunately, some things cannot be represented as a string

Yea I didn't mention it, but thats one of the things I would want to.

>This is then completely useless if you can't reuse a value multiple times by referring to it as a variable. It makes more sense to inline everything.

Just for better readability of the string syntax.

> ...what?

didn't you understand? :D

> This is a misleading name, plus it would add BJ-like functions. It would make more sense to alias "CreateEffect(*)" with "DestroyEffect(AddSpecialEffect(*))"

Congratz, thats what I introduced.

> Some effects don't have a death animation, and so they are never shown.

Thats why CreatePermanentEffect(..) exists. The function names can still be changed ..

> for the initializer. An initializer will never take, or return anything. This syntax will also separate it from actual methods/functions.

good point.

_____________


> I programmed python for two years and I know how nasty indentation is when you want to maintain your code -.-

I like new users being forced to indentate, cause that increases code beauty. And I think it's still better readable than with {}.

>making null be converted to nothing seems pointless to me. We could always just omit the whole thing and not add any confusion oO

No, I meant that you could end function declarations on several ways:
func test(unit u):null
func test(unit u):nothing
func test(unit u):
func test(unit u)

> A good idea. Using "pickfunc" though is a little bit... Strange. No need to craft new keywords... Using

names are nothing other than sound and smoke :p

>What for? Just for supporting your "pickfunc"-renaming-scheme? Apart from that, it just adds to confusion and makes it harder for oldschool jassers to adapt.

Yea, and it integrates a global GROUP ;)

> PS: Your naming conventions are aweful oO I hope you don't use them when you code for real =D

never fear ;)

> Since that allows us to distinguish between declaration and a simple assignment. I think it also makes it much easier to parse...

why? When the compiler finds a "e = null" whether it has already a meaning for e or it has to declare the var and set it.

interesting is sth. like this:

JASS:

class test
   static tempInstance
   integer count

   func onTimer()
      this = .tempInstance 
      .count = .count - 1
      BJDebugMsg(.count)
      if .count = 0 
         PauseTimer(GetExpiredTimer())
         sfx = CreatePermanentEffect(...)
         Wait(3.)
         RemoveEffect(sfx)

// compiles to:

globals
   integer test__tempInstance
   integer array test__count
endglobals

function onTimer takes nothing returns nothing
   local integer this = test__tempInstance
   local effect sfx = null  // &lt;= this is what I mean
   set test__count[this] = test__count[this] - 1
   if test__count[this] == 0 then
      call PauseTimer(GetExpiredTimer())
      set sfx = AddSpecialEffect(...)
      call Wait(3.)
      call DestroyEffect(sfx)
   endif
endfunction
 

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
Because you might want to change during iterations because you find out stuff works better as widget than as unit/you want to use reals instead of integers/....
As long as its just one variable, thats all fine. But once you start to build a system around it, phew...

If you're building a system and you end up having to read your own code with that sort of syntax, you're going to have more problems understanding the code than you will simply switching a few types here and there...

>This is then completely useless if you can't reuse a value multiple times by referring to it as a variable. It makes more sense to inline everything.

Just for better readability of the string syntax.

That's not more readable.

> ...what?

didn't you understand? :D

Not really. SerraAvenger's post did explain it a bit though.

> This is a misleading name, plus it would add BJ-like functions. It would make more sense to alias "CreateEffect(*)" with "DestroyEffect(AddSpecialEffect(*))"

Congratz, thats what I introduced.

What I meant was, I don't really want a compiler that would invent their own aliases for me. Aliases would be nice, but have people declare them, don't insert your own.

> Some effects don't have a death animation, and so they are never shown.

Thats why CreatePermanentEffect(..) exists. The function names can still be changed ..

This is the reason why I don't think you should insert your own aliases. They will cause confusion if they are embedded in your language.
I like new users being forced to indentate, cause that increases code beauty. And I think it's still better readable than with {}.[/QUOTE

The key words here being "new users". While I like how python code looks, I do sometimes want to indent something further.

No, I meant that you could end function declarations on several ways:
func test(unit u):null
func test(unit u):nothing
func test(unit u):
func test(unit u)

You could also use 'void'. I personally like this syntax, though I'm a little confused as to what methods will look like.
 

GetTriggerUnit-

DogEntrepreneur
Reaction score
129
I personally think that Executor's syntax is messy and hard to read. I would not use the language if that syntax was used. {} function/endfunction, please.
 

Lyerae

I keep popping up on this site from time to time.
Reaction score
105
First-draft of the definition... It's pretty incomplete, and all, but it'll give you an idea of the syntax and features. Just wanted to know there is progress being made. :thup:

Let's get started.

Blocks are created using "{" and "}" blocks. These can be used anywhere where normal JASS-Style blocks can be used.
Let's show an example for a function.

JASS:
function blocksTest takes nothing returns nothing
{
	call BJDebugMsg(&quot;Hello World&quot;)
}

This will be compiled into this:

JASS:
function blocksTest takes nothing returns nothing
	call BJDebugMsg(&quot;Hello World&quot;)
endfunction

Function Declarations.
I like C and C++ style declarations for functions, so I'll be including them.
You can use normal JASS-style functions if you don't like these, but these are "standard".

Incase you don't know C, here's an example:

JASS:
nothing Init()
{
	call BJDebugMsg(&quot;Hello World&quot;)
}

Lets break this down.

nothing

This is the return type. All valid JASS types can be put here.

[ljass]Init[/ljass]

This is the function name. You know what these are.

[ljass]()[/ljass]

This is the arguement list. You need to specify the type of variable, and the arguement name. You can seperate multiple arguements using
a comma (",").
As we learnt blocks before this, and you should know JASS before you learn Onyx, I'll leave it at that.

Freeform globals.

Freeform globals are easy. Just declare them like you would normally, but without the "globals" and "endglobals" keyword.
Example:

[ljass]hashtable ht = InitHashtable()[/ljass]

Libraries.
People like the vJASS style libraries, so I'll use those.
They're pretty much the same as vJASS libraries.


Namspaces.
These any Onyx's own implementation for libraries. They are close to vJASS libraries, but have some differences, most of which will come later in the definition.
Here's a commented example:

JASS:
namspace namespaceTestOne // declare the namespace, call it namespaceTestOne.
{
	private constant string msg = &quot;HAI&quot; 
			constant string anotherMsg = &quot;Hello World&quot;
			
	nothing Init() // Init is automatically called inside of a namespace
	{
		call BJDebugMsg(msg)
		call BJDebugMsg(anotherMsg)
	}
}


Structures (structs)
Structs aren't like vJASS structs, believe it or not. I don't like how vJASS implements structs, to be honest.
So I'll be basing structs off of C.

Here's an example:

JASS:
struct Data
{
	real x
	real y
}


That's all it can do. It can hold instance-based data. Cool, huh? If not, well meh.

To create an instance:

JASS:
nothing Init()
{
	Data d = data.create()
}


That'll return an unused ID for a struct.
How do we destroy, and recover the ID?
JASS:
nothing Init()
{
	Data d = data.create()

	d.destroy()
}


Access the members using the identifier.

JASS:
nothing Init()
{
	Data d = data.create()
	
	d.x = GetUnitX(GetTriggerUnit())
	d.y = GetUnitY(GetTriggerUnit())

	// stuff with d.x and d.y

	d.destroy()
}


You can extend structs using the "using" keyword.
So, this:

JASS:
struct DataA
{
	real x
	real y
}

struct DataB
{
	using DataA as a
}


You can now...

JASS:
nothing Init()
{
	DataB b = DataB.create()

	a.x = GetUnitX(GetTriggerUnit())
	a.y = GetUnitY(GetTriggerUnit())

	// moar stuff

	b.destroy() // destroys everything, cleans ID for both structs.
}


That's about it for structs.

Just remember, this is all subject to change at anytime. :D
 

SerraAvenger

Cuz I can
Reaction score
234
small typo:
namspace <- missing e :D
JASS:

struct DataA
{
	real x
	real y
}

struct DataB
{
	using DataA as a
}


No multiple inheritance please...

JASS:

struct DataA
{
	real x
	real y
}

struct DataB &lt; DataA  
{

}


Should be fine.


Now to
JASS:

	b.destroy() // destroys everything, cleans ID for both structs.

I'm not sure I want to use such syntax.
I think it would be much better to use
JASS:
Destroy( b )

Or something...
That way, we will be forced to use the very same syntax for both native types and structs.

Again, the question remains:
How will methods/static methods be declared and used?
I think using something go-like (see golang.org) would be best.
JASS:

nothing object.Destroy ( object s ) // object is the struct baseclass. All structs automatically  &quot;&lt; object&quot; if they are not extending another struct = )
{
   // ...
}

static object object.New ( )
{
  object new
  // allocate free index to new
  Initialize( new )
}

struct test // &lt; object <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite2" alt=";)" title="Wink    ;)" loading="lazy" data-shortname=";)" />
{
    integer X
    integer Y
}
nothing test.Destroy( test t )
{
    Super( t ) // Invokes the method of the superclass 
    // same as
    // object.Destroy( t )
}
integer test.GetY( test t ) {
    Y[ t ] + 5 // Note this***
}

initializer {
  test t = New( ) // tries to invoke test.New(), then object.New()
  BJDebugMsg( I2S( GetX( t ) ) ) // yes, getters and setters get declared automatically IF THEY AREN&#039;T DECLARED EXPLICITELY!***
  Destroy( t )
}


in short:
JASS:
(static) &lt;RETURN_TYPE&gt; &lt;TYPE&gt;.&lt;NAME&gt;( &lt;ARGS&gt; ) {}
// is similar to...
(static) method &lt;NAME&gt; takes &lt;ARGS&gt; returns &lt;RETURN_TYPE&gt;

methods are declared outside of the struct by using <TYPE>.<NAME>.
static methods just have a static infront of their name.
Same might go for private/public/protected.

***Getters and setters are declared implicitely.
If you are inside of the struct's methods, you can alternatively access them directly with an array syntax, like in the example above:
JASS:

integer test.GetY( test t ) {
    Y[ t ] + 5
}


In fact, the automatically generated code could easily look like this:
JASS:

&lt;VAR_TYPE&gt; &lt;TYPE&gt;.Get&lt;VAR_NAME&gt;( &lt;TYPE&gt; self ) {
    &lt;VAR_NAME&gt;[ self ] 
}
nothing &lt;TYPE&gt;.Set&lt;VAR_NAME&gt;( &lt;TYPE&gt; self, &lt;VAR_TYPE&gt; value ) {
    &lt;VAR_NAME&gt;[ self ] = value
}


and for arrays it would be
JASS:

&lt;VAR_TYPE&gt; &lt;TYPE&gt;.Get&lt;VAR_NAME&gt;( &lt;TYPE&gt; self, integer field ) {
    &lt;VAR_NAME&gt;[ self ][ field ]
}
nothing &lt;TYPE&gt;.Set&lt;VAR_NAME&gt;( &lt;TYPE&gt; self, integer field, &lt;VAR_TYPE&gt; value ) {
    &lt;VAR_NAME&gt;[ self ][ field ] = value
}


@exe
No, I meant that you could end function declarations on several ways:
func test(unit u):null
func test(unit u):nothing
func test(unit u):
func test(unit u)
The more, the worse.
 
General chit-chat
Help Users

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top