Итак, сразу же продолжу. В конференции сегодня предложил разобрать свежий код, чтобы расспросили всё, что непонятно. Но ответ был только один - "рассказать построчно". Т.е. непонятно, вроде бы, всё?
Тогда лучше тему продолжить на форуме. Итак, код:
code forth
forth:: escape_to_castle ( -- )
self p.castle
?dup unless
ru: У Вас нет замка
en: You have not castle
type
exit
then
self p.castle-owner-restart-point
jump
;
Как и положено в Форте, разберём его слово за словом. Ибо единственным разделителем у нас является пробел (табуляция, перевод строки и т.п.)
forth::. Нестандартное слово. Вариант слова
:, которое определяет новое слово, но компилирует его не в текущий словарь, а всегда в FORTH. Скилловы при выполнении типа CODE ищут указанное слово только в базовом словаре. А вдруг мы потом этот код внутрь модуля спрячем?
escape_to_castle. Просто имя нового слова.
( -- ). Комментарий. Описывает входные аргменты слова (до "--") и выходные данные. В данном случае и тех, и других нет. Слово ничего не принимает со стека и ничего не возвращает. Вообще, строго формально, слово тут одно - "(". Это слово берёт со входного потока всё до символа ")" и игнорирует.
self. Возвращает объект игрока (в общем случае - любого владельца Форта). После выполнения на стеке окажется ссылка на соответствующий L2Player. Нотация записи такая: ( — player )
p.castle. Снимает со стека ссылку на игрока (подсказка в имени - "p.") и возвращает в стек ссылку на замок игрока или null, если клана и/или замка нет. Нотация стека: ( player — castle )
?dup. Стандартное слово, которое дублирует на стеке число (как делает просто "dup") только если оно не равно false/0/null/"". Иначе - ничего не делает. Т.е. нотация будет или ( castle — castle castle ) или ( null — null )
unless. Нестандартное слово, имя которого взято из Perl'а. Там unless(...) - это аналог if(!...), т.е. для Форта это примерный аналог "not if". Идущий следом код будет выполняться только если на входе были false/null/""/0. До слова "then", которое является аналогом "endif" в других языках
(напомню: "condition if doing then"). Всегда снимает со стека один параметр, т.е. ( some — ) а дальше, если была ложь, то выполняет код до then, иначе - сразу переходит к выполнению того, что за then.
Дальше у нас код, выполняющийся, если на стеке был null, т.е. замка не было.
ru: У Вас нет замка. Берёт текст до конца строки кода. Если стоит русский язык игрока, то поместит этот текст на стек как строку. ( — "текст" ) или ( — )
en: You have not castle. Аналогично для английского языка или, если язык был не определён (поэтому en: всегда должна идти после ru:). ( — "text" ) или ( — )
После этих двух слов на стеке обязательно будет хоть одна строка. Т.е. по ним в комплекте: ( — "text/текст" )
type. Отсылает игроку "sendMessage" с текстом, который снимет со стека. ( "сообщение" — ).
exit. Аналог return. Выход из слова.
then. Конец условного блока. Поскольку вышли мы из него, каламбур, безусловно, то дальше мы выполняемся только в том случае, если замок у игрока есть.
К этому месту на стеке у нас (благодаря связки (castle) ?dup unless ) лежит ссылка на замок. Т.е. ( castle )
self. Было выше. Итого: ( castle player — )
p.castle-owner-restart-point. Слово, снимающее со стека ссылку на игрока ("p.") и берущее ещё одним параметром ссылку на замок. В ответ - возвращает на стеке три числа - x, y и z. Координаты одной из случайных точек респавна владельцев замка. ( castle player — x y z )
jump. Телепортация по переданным слову координатам. ( x y z — )
;. Конец определения слова. Возврат к режиму интерпретации.
Всё. Задавайте вопросы