WarCraft 3: 1. Основы

WurstScript

Блоки кода

WurstScript использует отступы для определения блоков кода, супротив фигурных скобок (подобно Java/cJass) или ключевых слов (подобно 'endif' в Jass/vJass). В качестве отступов допустимо использовать табуляцию и пробелы, однако их смешение бросит предупреждение. В дальнейшем мы будем использовать термин "табуляция" для обозначения как самого символа табуляции так и отступа из 4х пробелов.
// Язык использующий фигурные скобки (Java/cJass)
if condition
{
    // Инструкции блока if
    ...
}
nextStatements
// Язык использующий ключевые слова (Jass/vJass)
if condition
    // Инструкции блока if
    ...
endif
nextStatements
// Язык использующий отступы (WurstScript/Python)
if condition
    // Инструкции блока if
    ...
nextStatements
Блок когда должен быть определен одной или более табуляций. Использование пробелов в качестве отступов не допускается (Прим. Пер.: Как уже говорилось выше, под табуляцией подразумевается либо сама табуляция, либо не менее 4х пробелов, другими словами, вы можете использовать пробелы, однако, если вы используете менее 4 пробелов, компилятор не воспримет этот блок как новый).
В общих случаях, инструкция внутри блока кода ограничивается концом строки, а каждая новая строка начинает новую инструкцию. Однако, существует ряд исключений:
  • Конец строки игнорируется после символов ( и [
  • Конец строки игнорируется перед символами ), ], . и ..
  • Конец строки игнорируется до или после следующих токенов .. +, * , -, div, /, mod, %, and, or,->
Вы можете использовать их для записи длинных выражений или заполнения длинного списка параметров в несколько строк, либо для цепочки вызовов методов (см. «Каскадный оператор»).
someFunc(param1, param2,
	param3, param4)

someUnit..setX(...)
	..setY(...)
     ..setName(...)
WurstScript старается избегать излишнего использования символов в своем синтаксисе, обеспечивая понятный и удобочитаемый вид, в то время как Jass имеет более подробную структуру.
Прим. Пер.: следует отметить важную особенность компилятора, не упомянутую здесь. Способ оформления блоков кода различается в зависимости от используемых инструментов. Если вы используете внешний редактор Visual Studio Code (что рекомендуется и подразумевается), вам следует придерживаться правил этого мануала. Если вы используете редактор карт WurstWE, вам следует помнить, что отступы не определяют блоки кода, для этого используются ключевые слова. Блок кода функции/класса/блока инициализации и т.д. должен заканчиваться ключевым словом end.

Пакеты

Wurst-код организован пакетами. Любой ваш код, так или иначе, должен быть заключен в пакет (package). Пакеты так же могут включать в себя другие пакеты посредством импорта (import), что позволяет использовать ресурсы (переменные/функции/классы и т.д). импортированного пакета. Пакеты могут иметь блок инициализации (init), код внутри которого будет выполнен сразу после загрузки карты.
package HelloWurst
// Чтобы использовать ресурсы из другого пакета вы должны 
// импортировать его в начале текущего пакета
import PrintingHelper

// Код, располагаемый в блоке init, будет выполнен  сразу 
// после загрузки карты
init
    /* Вызов функции print из пакета PrintingHelper */
    print("Hello Wurst!")
Более подробно см. в главе "Пакеты".
Вы по прежнему можете использовать обычный Jass-код вне пакетов. Wurstpack World Editor будет парсить Jass код (и vJass, если JassHellper включен) в дополнение к компиляции Wurst-кода.

Функции

Объявлении функции включает в себя имя функции, список формальных параметров и тип возвращаемого значения. Тип возвращаемого значения указывается после списка формальных параметров посредством ключевого слова returns. Если функция ничего не возвращает, объявление возвращаемого значения опускается.
// Эта функция возвращает наибольшее из двух значений
function max(int a, int b) returns int
    if a > b
        return a
    else
        return b

// Эта функция выведет на экран сообщение с наибольшим из двух значений
function printMax(int a, int b)
    print(max(a,b).toString())

// Функция, которая ничего не принимает и ничего не возвращает
// Пустые скобки вместо устаревших "takes nothing" и отсутствие "returns nothing"
function foo()
    ...

function foo2(unit u) // параметры
    RemoveUnit(u)

function bar(int i) returns int // "returns" [тип]
    return i + 4

function blub() returns int // функция без параметров
    ...
    return someArray[5]

Переменные

Глобальные (локальные) переменные могут быть объявлены где угодно внутри пакета (функции). Объявление констант производится посредством ключевого слова constant или let. Объявление обычных переменных начинается с ключевого слова var либо с указания типа переменной.
// Объявление константы — тип будет определен исходя из значения инициализации
constant x = 5

// Та же константа, но с явным указанием типа
constant real x = 5

// Объявление переменной
var y = 7

// Объявление переменной с явным указанием типа
int y = 7

// Объявление массива
int array a

// Внутри функции
function getUnitInfo( unit u )
    player p = u.getOwner()
    var name = u.getName()
    print( name )
    real x = u.getX()
    real y = u.getY()
    let sum = x + y
В действительности, Wurst не генерирует константы на этапе компиляции. Переменные объявленные с применение ключевого слова let или constant не будут преобразованы в Jass-константы, однако, при попытке изменить значение этих переменных, компилятор выдаст ошибку.

Каскадный оператор

См. так же раздел «Классы» и «Расширяющие функции».
Использование каскадного оператора .. схоже с оператором . и может применяться для вызова методов объекта. Однако, вместо возврата результата работы метода, каскадный оператор возвращает экземпляр, чей метод был вызван. Это позволяет вызывать несколько методов одного объекта подряд.
Небольшой пример
CreateTrigger()
    ..registerAnyUnitEvent(EVENT_PLAYER_UNIT_ISSUED_ORDER)
    ..addCondition(Condition(function cond))
    ..addAction(function action)
Этот код эквивалентен следующему
let temp = CreateTrigger()
temp.registerAnyUnitEvent(EVENT_PLAYER_UNIT_ISSUED_ORDER)
temp.addCondition(Condition(function cond))
temp.addAction(function action)

Сокращенное присваивание

Wurst поддерживает следующие виды сокращенного присваивания
i++  	    // i = i + 1
i--         // i = i - 1
x += y      // x = x + y
x -= y      // x = x - y
x *= y      // x = x * y
x /= y      // x = x / y
Поскольку эти сокращения просто транслируются в эквивалентные им операции, они могут быть использованы с перегруженными операторами.
Прим. Пер.: следует отметить операторы, идентичные операторам инкремента и декремента в C++. Здесь это только-лишь короткая запись арифметических операций, которую не получится применить внутри других выражений.

Соглашение об именовании

Wurst призывает использовать следующее соглашение об именовании, ради сохранения чистоты кода и его удобочитаемости:
  • В общем случае, имена должны придерживаться так называемого Верблюжьего Регистра (CamelCase) — каждое новое слово в имени пишется слитно с предыдущим и начинается с символа верхнего регистра
  • Имена функций должны начинаться с символа нижнего регистра (myFuncName)
  • Имена переменных так же должны начинаться с символа нижнего регистра (myVariableName)
  • Имена констант содержат исключительно символы верхнего регистра, с разделением слов посредством символа "_" (MY_CONSTANT_NAME)
  • Имена классов/модулей/интерфейсов/пакетов должны начинаться с символа верхнего регистра (MyClassName/MyPackageName)
  • Имена кортежей должны начинаться с символа нижнего регистра (myTupleName)
  • Имя должно подбираться описательно, прозрачно указывая на назначение его владельца

Просмотров: 198

Doc #1 - 3 месяца назад 2
Если вы используете внешний редактор Visual Studio Code (что рекомендуется и подразумевается)
Когда я пробовал подразумевался эклипс, сейчас уже нет?
GetLocalPlayer #2 - 3 месяца назад 0
Doc, да, теперь VSCode. Даже в самом руководстве информация об эклипсе весьма обрывиста.