找回密码
 点一下
查看: 3858|回复: 28

Galaxy++ editor by Beier

[复制链接]
发表于 2011-6-1 10:11:06 | 显示全部楼层 |阅读模式
不错的Galaxy编辑器,已经支持中文输入,支持直接将脚本文件插入地图测试。
原下载地址为:http://www.sc2mapster.com/assets/galaxy-editor-beier/
ftp://46.163.69.112/Releases/


1.90版本更新说明


Change log

  • Added support for allowing characters in the range [0x0100 - 0xFFFF] to apear in strings and as identifiers.
  • Text coloring algorithm has been rewritten. Structs are no longer colored, and writing /*/*/* no longer results in an error.
  • Indentation algorithim has been rewritten due to some issues with the previous algorithm.
  • Varios warnings about the same thing has been joined into a single expandable error message.
  • Changed string obfuscation to work for fields without method calls in them.
  • Added a notation to quickly write triggers. See documentation.
  • Fixed a bug with the suggestion window that occured when scrolling down to the end.
  • Added an option to use tabs instead of 4 spaces.
  • Integer literals in the range [0, 255] are now considered bytes.
  • Added handle and char types (theese are also galaxy types)
  • Having no strings in a project will no longer result in an exception if string obfuscation is selected
  • Fixed a bug where pointer refferences inside a new expression would not be converted correctly.
  • Fixed an error where struct methods were not always declared before use in the output.


软件说明

Documentation



General


Galaxy++ is a programming language that extends upon the original galaxy language, adding a lot more features. This means that any galaxy code you have should run exactly the same way when feeding it to the galaxy++ compiler.
Like most other programming languages, comments and whitespace is ignored by the compiler, so they can be placed pretty much anywhere without changing the behavior of the program.
If you feel some of your questions still go unanswered after reading this, or you find errors in the documentation, please pm me or post a reply. I will get back to you, and perhaps add to the documentation.

Compiler options


Although they might not classify as a language feature, I feel it's relevant to highlight some of the options in the compiler.

Obfuscation


There are a couple of tools for obfuscating the code. One is to rename everything to short names such as a, b, c. The other is to obfuscate string literals. What this will do is to "encrypt" every string so it is not readable by humans, and "decrypt" them when starting the map.
Please note that no code obfuscation can completely prevent others from reading, understanding and stealing your code. It just makes it difficult.

1: Declarations



1.1: Namespaces


You have the option to define a namespace for each file. The namespace must be declared as the first thing in the file. You declare a namespace with

#namespace myNameSpace
By default, you can only directly refer to things in your own namespace or the default namespace. If you want to refer to declarations outside your current namespace, you can use the dot notation. For example, if the method method() is in the namespace otherNS you can refer method with

otherNS.method()
If you want to be able to directly refer to everything in another namespace you can add a #using declaration. These must be at the top of the file, directly below the namespace declaration if present.

#using otherNS

1.2: Initializers and Library definitions


Initializes are basically methods that are run at first, when the map loads. Unless you made your own call to initialize the standard library, this call will be inserted before calling the initializers. You can make a simple initialize with

#Initializer{[statements]}
The initializers can also contain data about a library you are defining. There are 4 different library fields: #LibraryName, #LibraryVersion, #SupportedVersions and #RequiredLibraries. An example of a library initializer is

#Initializer(#LibraryName = "my library"#LibraryVersion = "enterprise",#SupportedVersions = "trial, basic"#RequiredLibraries = "other lib 1:version2, (otherLib2:v1.7.4)"){[statements]}
All the library fields are optional, except you need both a name and a version in order for others to add it as a requirement. If your library version is not on the list of supported versions, it will be added. You may not use “:”, “(“, “)” or “,” in the name or versions, and all leading and trailing whitespace is ignored. The method block is optional. It can be replaced with a semicolon.
If an initializer has defined any required libraries, the initializers of those libraries will be called first. In case of cyclic dependencies, a warning is reported, and as few dependencies as possible are ignored.

1.3: Includes


Any custom includes are ignored. Includes will be inserted by the compiler as needed, but all code except for the standard libraries are required in the project.

1.4: Methods


Unlike normal galaxy, it is not needed to have defined the method before using it.

1.4.1: Inline methods


Inline methods are marked with the keyword #inline. When compiling a call to an inline method, the contents of the method is inserted instead of calling the actual method. This is done in a way so that there is no semantic difference to calling the method instead.

#inline int method(...){...}
Note that inline methods may not be recursive i.e. they may not be called from themselves.

1.4.2: Trigger methods


There is a #trigger keyword in galaxy++, but it no longer has any effect. It was previously used to identify methods that were triggers, but this is now done by searching for a string in a call to TriggerCreate. The keyword is kept for backward compatibility.

1.4.3: Reference parameters and extra return values


You can mark parameters with the #ref or #out keywords. Arguments passed to parameters marked with one of these must be variables. The effect of #ref is that any changes done to the variable during the method call is reflected back in the calling method after the call. #out is similar. Like with #ref the changes done to this variable will also be done after the call, but unlike #ref, it is required that the called method assigns a value to an #out parameter, and he cannot read the parameter before he assigns a value to it. After compilation, an #out parameter is not actually passed to the function, it is only returned, so it can be used as extra return values.

string[17] strings;string Next(#ref int i, #out bool hasNext){hasNext = i + 1 < strings.length;if (hasNext)return strings[++i];return "";}

1.4.4: Passing bulkcopy data


Another thing to not is that it is now possible to pass types that would otherwise result in a bulk copy error between methods. This includes struct types and arrays. From your point of view, they are passed in exactly the same way as normal types. The compiler will send them via the data table instead.

1.5: Fields


Fields are pretty much what they are in galaxy, except that you don't have to have defined them above where you use them.

1.6: Structs


Like with fields and methods, you don't have to define structs above where you use them.
A new thing in galaxy++ is that structs can now contain methods. Simply place a method inside a struct, and that method will be a struct method. Struct methods will always be called with a specific instance of the struct. It is possible to directly refer to the members of the struct that is being called on by just typing the name of the member.

struct Foo{int[10] elements;int GetSum(){int sum = 0;for (int i = 0; i < elements.length; i++)sum += elements;return sum;}}...void Method(Foo foo){if (foo.GetSum() > 9000)......}

1.7 Bank preload statement


The preload bank statement from GUI is not an actual method call in code, so I added extra functionality to call this.

#PreloadBank("BankName", 2);
I felt that it would be misleading to place it inside functions, since it is not a statement which is executed there, but rather just a message to Starcraft II to load the bank when loading the map. Therefore it is placed out next to methods and fields. Note that the name and playerNr must be literals. I.e. you can not use any kind of variables or expressions other than what you see above.

1.8 Trigger declaration


There is a shot way you can choose to specify triggers. Use the following notation

#trigger TriggerName{#events{//Add the events the usual wayTriggerAddEventMapInit(TriggerName);}#conditions{if (...)return false;else if (...)return true;}#actions{//Add the actions of the trigger the usual way.}}
Both the events and conditions section are optional. The conditions are only tested if testConds are true, and actions are only run if runActions are true, and testConds are false or the conditions return true.
If nothing is return from the conditions, true is assumed.
You can reference testConds and runActions from within the conditions and actions sections.
You can reference the trigger variable with the name of the trigger as done in the above example in events. You can also call the trigger function as you would normally be able to by typing TriggerName(<testConds>, <runActions>);
The return type in the actions section is void.

2: Statements


A statement is basically the members of functions where it doesn't make sense to talk about it having a type. Examples of statements in galaxy are while statements, if statements and expression statements. In this documentation I will only cover statements that are new or have added functionality in galaxy++.

2.1: If statements


In galaxy you were forced to place a block inside if statements, now you can also place a single statement without the block.

if (i < ar.length)i++;

2.2: For statements


I added for statements in galaxy++.

for ([init]; [test]; [update])[body]
Basically, what it will do is first execute the init, then for as long as the test evaluates to true, the body and then the update is executed. Like GUI for sentences.

2.3: Switch statements


I also added switch statements.

int ammount;bool isRanged = false;#switch (GetUnitTypeString()){#case "Zergling":ammount = 100;break;#case "Marine":isRanged = true;#case "Zealot":ammount = 50;break;#case GetSuperUnitName():ammount = 1;break;#default:ammount = 10;break;}
It will test the expression it gets in the first parenthesis against every case in the order they are listed. When one of them equals, it will execute the contents of the case. If no cases were equal to the expression, the contents of default will be executed. Note that it is possible to fall through to the next case if one doesn't write break, like it is done from marine to zealot. Another thing to mention is that the method GetUnitTypeString() will only be called once, no matter how many cases there are. Also, GetSuperUnitName() is only called if none of the above cases matched.

2.4: AsyncInvoke statement


The AsyncInvoke statement will call a method in a new thread, and continue its own thread. This is done by running a new trigger, so the operator stack is also reset in the process (in case you are wondering, this is a good thing :)). If you wanted to call a method like

int CallMe(int a, bool b){...}
you could write

#AsyncInvoke<CallMe>(2, false);
In case CallMe is in another namespace called OtherNS, you can write

#AsyncInvoke<OtherNS.CallMe>(2, false);
Since the target function is called in a new thread, it is not possible to return a value from it, so any return values are ignored.

2.5: Local declarations


I made it possible to make multiple local declarations in one statement as long as they are of the same type.

int a = 2, b, c = a + 1;

3: Expressions


Expressions are everything that can have a type. Examples of this is method calls, references to local, global or struct variables, binary operations (+, -, *, /, %), etc. Like with statements, I won't cover the expressions that are the same in galaxy as in galaxy++.

3.1: The ++ and -- expressions


I added support for the ++ and -- expressions. They can be placed before and after a variable, and will increment or decrement the variable. When placed after the variable, the current value of the variable is placed where the expression is, and then the variable is updated. For instance, if you write

int i = 0;ar[i++] = i;
then then you will have set the 0th index of ar to 1. Placing it before the variable will update the variable, and then the updated value is placed where the expression is. E.g.

int i = 0;ar[++i] = i;
will set the 1st index of ar to 1. This is most commonly used as a quick way of writing i = i + 1;

3.2: Invoke


Similar to the AsyncInvoke statement, this expression will call the target method via a trigger in order to reset the operator stack. Unlike  AsyncInvoke however, this is not done in a separate thread. This means that all return values can still be fetched.

#Invoke<namespace.methodName>(args);

3.3: Assignments


With galaxy++ you can now place assignments inside expressions rather than just in statements. For instance you can write

a = b = c = d = 2;
and all of them will have the value 2. Note that the type of the assignments are the type of the left side. What this means is that for instance if c is of type fixed, and b is an integer, you will get an error since fixed is not assignable to int.

3.4: Array length


You can get the length of an array by calling .length on it.

String[2] ar;return ar.length;    //returns 2

3.5 Casts and implicit casts


I added cast expressions. They are a quick way of converting between types that can be converted between.

fixed f = 2.2;int i = (int) f;
I also made some implicit casts, which means that between some types the cast occurs automatically.

int i = 2;UIDisplayMessage(playergroupAll(), c_messageAreaSubtitle, "i = " + i);
In this example, the i is cast to a string, then the two strings are concatenated, and the whole string is cast to a text.

Pointers


This is placed a little out of place compared to the structure of the rest of the documentation, but I thought I would keep everything regarding pointers together.

Pointer types


You can define a type as a pointer by appending *. For instance

int* i;string** s;
Here i will be a pointer to an int, and s will be a pointer to a pointer to a string.

Dynamic array types


You can define a dynamic array type by not specifying array bounds. For instance

int[] ar1;int*[] ar2;
Here, ar1 is a dynamic array of type int, and ar2 is a dynamic array of pointers to int's.

The * expression


If you have an expression of pointer type, and you would like to get the value of that expression, you prefix it with *. For instance

void foo(string* s){UIDisplayMessage(PlayerGroupAll(), c_messageAreaSubtitle, (text)(*s));}
Here, the *is needed to get the actual contents of s. Also note that *s is in a parenthesis. If this was not the case the compiler would have tried to multiply a variable called text with the variable s.

The -> expression


The -> expression is really just a quick way of writing (*foo).bar.

struct Foo{int bar;}void method(Foo* foo){foo->bar = 2;(*foo).bar = 2;}
Here, the two statements are equivalent. In both cases, bar will be set to 2.

The #new expression


To create new pointers or dynamic arrays, use the #new expression. For instance

int* i = #new int();int[] ar1 = #new int[*i]();
Here, i is initialized to a new integer, and ar1 is initialized to a dynamic array of size *i (which will be 0 in this case).
Note that the #new expression allocates a new instance in the data table. To avoid memory leaks, remember to call #delete after you are done with the instance.

The #delete statement


The delete expression will remove the supplied pointer or dynamic array from the data table. You should make sure that you call #delete if you are done with your pointer or dynamic array. Note that the #delete statement will only remove the actual pointer you supply to it. So writing

void foo(int*[] intAr){#delete intAr;}
Will remove the array, but will not remove any of the child pointers. If you wish to purge all allocated instances, you can clear the global data table with the method.

DataTableClear(true);
So, note that you shouldn't call this unless you wish to lose all pointers and dynamic arrays.

Galaxy editor v1.9.0绿色版.zip

1.62 MB, 下载次数: 103

Galaxy editor v1.9.0安装版.rar

1.74 MB, 下载次数: 18

评分

参与人数 1威望 +2 收起 理由
麦德三世 + 2 ~~zhege&nbsp;&nbsp;haibucuo

查看全部评分

发表于 2011-6-1 21:27:29 | 显示全部楼层
支持中文string?
回复

使用道具 举报

 楼主| 发表于 2011-6-1 21:33:32 | 显示全部楼层
支持自动转换
注入地图时转换成编码
回复

使用道具 举报

发表于 2011-6-1 21:34:37 | 显示全部楼层
.net 4.0
回复

使用道具 举报

发表于 2011-6-1 22:01:44 | 显示全部楼层
装个呗~~难不成你在用mac?~~
回复

使用道具 举报

 楼主| 发表于 2011-6-5 21:34:52 | 显示全部楼层
更新1.92,手机不方便转发,自己去原地址下载
回复

使用道具 举报

发表于 2011-6-6 13:31:05 | 显示全部楼层
图片图片都是些神马?
回复

使用道具 举报

发表于 2011-6-6 13:31:31 | 显示全部楼层
你还真是无法无天..
回复

使用道具 举报

 楼主| 发表于 2011-6-6 14:18:18 | 显示全部楼层
又开始屠版了
回复

使用道具 举报

发表于 2011-6-11 00:15:41 | 显示全部楼层
回复

使用道具 举报

 楼主| 发表于 2011-6-12 11:16:55 | 显示全部楼层
最新已经是2.05了……鼠标上还有点小问题,另2.0不支持中文输入
回复

使用道具 举报

发表于 2011-6-13 17:21:11 | 显示全部楼层

回 8楼(疯人¢衰人) 的帖子

回复

使用道具 举报

发表于 2011-6-15 00:10:26 | 显示全部楼层
在上面写了一些函数按下Compiled and run然后可以了,但是那些代码怎么注入到地图里面去啊?我按下Compiled and save但是弹出Unable to open file。。。。。,于是用mpq把galaxy脚本文件添加进去就可以了,但是地图原来的GUI上面的触发都无效了
回复

使用道具 举报

 楼主| 发表于 2011-6-15 06:14:57 | 显示全部楼层
设置里有工程设置,可以选择工程对应地图
回复

使用道具 举报

发表于 2011-6-15 09:25:15 | 显示全部楼层
现在是2.1.0了:http://static.sc2mapster.com/con ... __editor_v2.1.0.zip

这个工具有个粘贴大量代码的时候,会很卡,这点很郁闷的说
回复

使用道具 举报

 楼主| 发表于 2011-6-15 09:42:47 | 显示全部楼层
回 14楼(mic) 的帖子
比sc2E快多了,卡是正常的,毕竟需要检查高亮什么的
回复

使用道具 举报

发表于 2011-6-15 11:59:17 | 显示全部楼层
已经设置了那张地图了,但是compiled and save选择那张地图,但是还是覆盖不了,但是unable to open。。。
回复

使用道具 举报

发表于 2011-6-15 13:39:23 | 显示全部楼层
卡应该是可以修复的,很多高亮的编辑器都不卡的说
回复

使用道具 举报

 楼主| 发表于 2011-6-15 13:53:13 | 显示全部楼层
回 16楼(frozenleave) 的帖子
确认那个地图没有被其他程序占用
回复

使用道具 举报

发表于 2011-6-15 17:15:15 | 显示全部楼层
额,我是直接创建一个工程然后Setting那里选择一张地图,按下compiled and save然后默认的名字是那一幅地图后面加上了Galaxy++后缀,但是无论我加不加这个后缀,点击确定,然后就说不能打开地图了,我编辑器没开应该没有被其他程序占用吧。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 点一下

本版积分规则

Archiver|移动端|小黑屋|地精研究院

GMT+8, 2024-8-8 07:23 , Processed in 0.324853 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表