SS13 для опытных программистов: различия между версиями
imported>Ohar м (Добавлена плашка) |
imported>Kysovich (Часть перевода) |
||
Строка 1: | Строка 1: | ||
{{Требуется перевод}} | {{Требуется перевод}} | ||
Похожие руководства: [[Структура кода SS13]] и [[Руководство по маппингу]] | |||
Значит, вы знаете, как писать программный код на других языках и хотите краткое руководство для понимания кода SS13? Этот гайд для вас. Вероятно, здесь представлена не вся информация, которую вам следует знать, но для начала её будет достаточно. | |||
== | == Синтаксис == | ||
* | *Точка с запятой в конце строки не является обязательной, | ||
* | *Циклы, процедуры, объекты, переменные и т.п. блоки определяются отступами (сходство с Python). Примеры: | ||
/obj | /obj | ||
var | var | ||
Строка 13: | Строка 13: | ||
i2 | i2 | ||
i3 | i3 | ||
идентично коду: (Крайне рекомендуется использовать подобный вариант разметки, для упрощения поиска объявлений переменных и процедур в дальнейшем) | |||
/obj | /obj | ||
var/i1 | var/i1 | ||
var/i2 | var/i2 | ||
var/i3 | var/i3 | ||
что в свою очередь эквивалентно: | |||
/obj/var/i1 | /obj/var/i1 | ||
/obj/var/i2 | /obj/var/i2 | ||
/obj/var/i3 | /obj/var/i3 | ||
* | *Руководство использует термин '''объект''' для любых определенных типов (см. [[#Variable types|Типы переменных]]), и '''obj''' для производных <code>atom/obj</code>, все из которых являются объектами, которые могут быть размещены на игровой карте. | ||
* | *Руководство использует термин 'подконтрольный ИИ' для описания поведения, связанного с игроком в роли [[ИИ]], контролирующего предмет. Термин 'подконтрольный игре' используется, отсылаясь к поведению, которое определяет сам скрипт. (Существ с подобным поведением обычно называют существами, подконтрольными ИИ, или NPC) <!--Что тут имелось в виду в оригинале?--> | ||
* | *Все унаследовано от родительских объектов. Если переменная определена в <code>/obj/item</code>, её не нужно будет (на самом деле, нельзя) определять в <code>/obj/item/weapon</code>. | ||
=== [http://www.byond.com/members/?command=reference&path=var | === [http://www.byond.com/members/?command=reference&path=var Переменные (Источник)] === | ||
Переменные - это база. В BYOND переменные общие, не существует большой разницы при определении строковых, числовых, булевых и т.д. (Как в PHP) | |||
==== [http://www.byond.com/members/?command=reference&path=var | ==== [http://www.byond.com/members/?command=reference&path=var Предопределенные переменные (Источник)] ==== | ||
В BYOND существует большое количество предопределенных переменных, самые основные из них: | |||
*'''[http://www.byond.com/members/?command=reference&path=proc%2Fvar%2Fsrc src]''' - | *'''[http://www.byond.com/members/?command=reference&path=proc%2Fvar%2Fsrc src]''' - эквивалентна объекту, содержащему процедуру или переменную. При определении принимает тот же тип, что и этот объект. (Аналогично <code>this</code> из Java или C++) | ||
*'''[http://www.byond.com/members/?command=reference&path=proc%2Fvar%2Fusr usr]''' - | *'''[http://www.byond.com/members/?command=reference&path=proc%2Fvar%2Fusr usr]''' - переменная сущности (моба) (<code>var/mob/usr</code>), содержит сущность игрока, исполнившего текущий оператор или чье действие в конечном счете вызвало текущую процедуру. '''Хорошее правило из практики: никогда не помещать <code>usr</code> в процедуру.''' Если <code>src</code> не будет верным выбором, лучше отправить другой аргумент в процедуру с необходимой информацией. <!--Мы, конечно, программисты, но тут автор невнятно пишет --> | ||
*'''[http://www.byond.com/members/?command=reference&path=proc%2Fvar%2Fargs args]''' - | *'''[http://www.byond.com/members/?command=reference&path=proc%2Fvar%2Fargs args]''' - список аргументов, принятых в процедуре или операторе. | ||
*'''[http://www.byond.com/members/?command=reference&path=datum%2Fvar%2Fvars vars]''' - | *'''[http://www.byond.com/members/?command=reference&path=datum%2Fvar%2Fvars vars]''' - список переменных-объектов. Если использовать имя переменной в качестве индекса списка, возвращает значение этой переменной. | ||
Больше переменных описано здесь: [[#SS13 common variable meanings|Предназначение основных переменных в коде SS13]] | |||
==== | ==== Определение переменных ==== | ||
===== | =====Базовое определение===== | ||
var/j | var/j | ||
var/i = 4 | var/i = 4 | ||
var/a, b, c | var/a, b, c | ||
===== | =====Комплексное определение===== | ||
Основной синтаксис: <code>var/type/variable_name = value</code> [http://www.byond.com/members/?command=reference&path=var (из источника)] | |||
Примеры: | |||
var/obj/item/I = new/obj/item | var/obj/item/I = new/obj/item | ||
[http://www.byond.com/members/?command=reference&path=operator%2F%40dt%3B I.name] = "Some item" | [http://www.byond.com/members/?command=reference&path=operator%2F%40dt%3B I.name] = "Some item" | ||
Определение блока данных (datum) и объявление переменной этого типа данных (test_datum): | |||
datum/test_datum | datum/test_datum | ||
var/test_variable = 0 // | var/test_variable = 0 //объявляем переменную test_variable | ||
proc/set_as(var/i) // | proc/set_as(var/i) //объявление процедуры в рамках test_datum | ||
test_variable = i // | test_variable = i //присваиваем test_variable значение из аргумента | ||
var/datum/test_datum/TD = new/datum/test_datum //TD | var/datum/test_datum/TD = new/datum/test_datum //TD будет указателем на блок данных типа test_datum | ||
TD.test_variable = 4 //Byond | TD.test_variable = 4 //Byond не знает о приватных переменных, так что можно присваивать им значение таким образом | ||
[http://www.byond.com/members/?command=reference&path=world world] [http://www.byond.com/members/?command=reference&path=operator%2F%26lt%3B%26lt%3B <<] TD.test_variable // | [http://www.byond.com/members/?command=reference&path=world world] [http://www.byond.com/members/?command=reference&path=operator%2F%26lt%3B%26lt%3B <<] TD.test_variable //вернет 4 всем подключенным пользователям | ||
TD.set_as(10) // | TD.set_as(10) //Вызовет процедуру set_as в блоке данных TD с аргументом 10 | ||
TD.test_variable // | TD.test_variable //вернет 10 всем подключенным пользователям | ||
==== | ==== Битовый флаг ==== | ||
Bitflags | Битовые флаги (Bitflags) - это переменные, использующие биты вместо чисел для определения условий. Битовые операторы: [http://www.byond.com/members/?command=reference&path=operator%2F%26 & (поразрядное И)] и [http://www.byond.com/members/?command=reference&path=operator%2F%7C | (Поразрядное ИЛИ)]. Данные операторы используют двоичную систему счисления для определения результата. Таким образом, [http://www.byond.com/members/?command=reference&path=operator%2F%26 13 & 3] вернет 1. ([http://www.byond.com/members/?command=reference&path=operator%2F%26 1101 & 0011 = 0001]) и [http://www.byond.com/members/?command=reference&path=operator%2F%7C 13 | 3 = 15] ([http://www.byond.com/members/?command=reference&path=operator%2F%7C 1101 | 0011 = 1111]) (см. [[#IF (ЕСЛИ)]]) | ||
==== | ==== Типы переменных ==== | ||
[http://www.byond.com/members/?command=reference&path=var | [http://www.byond.com/members/?command=reference&path=var Источник] | ||
*[http://www.byond.com/members/?command=reference&path=datum datum] - | *[http://www.byond.com/members/?command=reference&path=datum datum] - обычный тип объекта (классы из Java) | ||
*[http://www.byond.com/members/?command=reference&path=atom atom] - | *[http://www.byond.com/members/?command=reference&path=atom atom] - атомарные переменные, превращаются в obj, turf, mob и area | ||
*[http://www.byond.com/members/?command=reference&path=turf turf] - | *[http://www.byond.com/members/?command=reference&path=turf turf] - плитки, составляющие полов, стен и космоса в SS13 | ||
*[http://www.byond.com/members/?command=reference&path=area area] - | *[http://www.byond.com/members/?command=reference&path=area area] - зоны, сгруппированные локации. Объединяют множество turf с похожими свойствами. Определяют электроснабжение, атмосферу и т.п. | ||
*[http://www.byond.com/members/?command=reference&path=mob mob] - | *[http://www.byond.com/members/?command=reference&path=mob mob] - живое существо, контролируемое игрой или игроком. | ||
*[http://www.byond.com/members/?command=reference&path=obj obj] - | *[http://www.byond.com/members/?command=reference&path=obj obj] - объекты, которые могут быть размещены на карте. | ||
*[http://www.byond.com/members/?command=reference&path=client client] - | *[http://www.byond.com/members/?command=reference&path=client client] - объект клиента, создаваемый при подключении игрока | ||
*[http://www.byond.com/members/?command=reference&path=list list] - | *[http://www.byond.com/members/?command=reference&path=list list] - список элементов. Первый элемент списка '''L''' определяется как '''L[1]''' | ||
*[http://www.byond.com/members/?command=reference&path=world world] - | *[http://www.byond.com/members/?command=reference&path=world world] - переменная, в которой могут быть определены глобальные переменные игрового мира. Переменные в world содержат все атомарные переменные, присутствующие в игровом мире. | ||
==== [http://www.byond.com/members/?command=reference&path=operator%2F%26lt%3B%26lt%3B%2Foutput | ==== [http://www.byond.com/members/?command=reference&path=operator%2F%26lt%3B%26lt%3B%2Foutput Вывод сообщений] ==== | ||
Самым простым способом вывода сообщений является использование оператора [http://www.byond.com/members/?command=reference&path=operator%2F%26lt%3B%26lt%3B%2Foutput '''<<''']. | |||
[http://www.byond.com/members/?command=reference&path=world world] [http://www.byond.com/members/?command=reference&path=operator%2F%26lt%3B%26lt%3B <<] "Hello World!" // | [http://www.byond.com/members/?command=reference&path=world world] [http://www.byond.com/members/?command=reference&path=operator%2F%26lt%3B%26lt%3B <<] "Hello World!" //Выводит сообщение всем клиентам, подключенным к миру. | ||
[http://www.byond.com/members/?command=reference&path=proc%2Fvar%2Fusr usr] [http://www.byond.com/members/?command=reference&path=operator%2F%26lt%3B%26lt%3B <<] "Hello usr" // | [http://www.byond.com/members/?command=reference&path=proc%2Fvar%2Fusr usr] [http://www.byond.com/members/?command=reference&path=operator%2F%26lt%3B%26lt%3B <<] "Hello usr" //Выводит сообщение только для пользователя, который вызвал процедуру с данным оператором. | ||
===== | ===== Вывод значений переменных ===== | ||
var/s1 = " | var/s1 = "Привет" | ||
var/s2 = " | var/s2 = "Мир" | ||
var/i = 2011 | var/i = 2011 | ||
[http://www.byond.com/members/?command=reference&path=world world] [http://www.byond.com/members/?command=reference&path=operator%2F%26lt%3B%26lt%3B <<] "[s1] [s2], | var/j = 2022 | ||
[http://www.byond.com/members/?command=reference&path=world world] [http://www.byond.com/members/?command=reference&path=operator%2F%26lt%3B%26lt%3B <<] "[s1] [s2], руководство написано в [i], переведено в [j]" //Возвращает "Привет Мир, руководство написано в 2011, переведено в 2022" | |||
==== | ==== Определение типов переменных в коде ==== | ||
Процедура [http://www.byond.com/members/?command=reference&path=proc%2Fistype istype()] вам пригодится. | |||
Пример: | |||
var/obj/item/weapon/W = new/obj/item/weapon/baton | var/obj/item/weapon/W = new/obj/item/weapon/baton | ||
if([http://www.byond.com/members/?command=reference&path=proc%2Fistype istype](W,/obj/item/weapon/baton)) | if([http://www.byond.com/members/?command=reference&path=proc%2Fistype istype](W,/obj/item/weapon/baton)) | ||
[http://www.byond.com/members/?command=reference&path=world world] << " | [http://www.byond.com/members/?command=reference&path=world world] << "Это - baton!" | ||
Второй аргумент необязателен, если опущен, переменная будет проверена на соответствие объявленному типу: | |||
var/obj/item/weapon/W = new/obj/item/weapon/baton | var/obj/item/weapon/W = new/obj/item/weapon/baton | ||
if([http://www.byond.com/members/?command=reference&path=proc%2Fistype istype](W)) | if([http://www.byond.com/members/?command=reference&path=proc%2Fistype istype](W)) | ||
[http://www.byond.com/members/?command=reference&path=world world] << " | [http://www.byond.com/members/?command=reference&path=world world] << "Это - weapon!" | ||
Стандартный код для получения аргументов из переменных, которые имеют тип, являющийся подклассом типа, с которым их обрабатывает текущая процедура (см. пример любой процедуры Attackby()). Обратите внимание, что приведенный ниже пример относится к процедуре, которая определена глобально и не привязана к объекту. Не имеет смысла делать это так, но это работает в рамках примера. Объекты /obj не имеют переменной 'amount', она определена в /obj/item/stack (как показано в упрощенном определении классов ниже. Также обратите внимание, где var/ используется, а где нет). | |||
/obj | /obj | ||
var/name = "Object" | var/name = "Object" | ||
Строка 123: | Строка 124: | ||
return [http://www.byond.com/members/?command=reference&path=operator%2F%40dt%3B S.amount] | return [http://www.byond.com/members/?command=reference&path=operator%2F%40dt%3B S.amount] | ||
Другой способ проделать такое. Он существует исключительно для демонстрации. | |||
proc/get_aount(var/obj/S) | proc/get_aount(var/obj/S) | ||
if([http://www.byond.com/members/?command=reference&path=proc%2Fistype istype](O,/obj/item/stack)) | if([http://www.byond.com/members/?command=reference&path=proc%2Fistype istype](O,/obj/item/stack)) | ||
return [http://www.byond.com/members/?command=reference&path=operator%2F%3A O:amount] | return [http://www.byond.com/members/?command=reference&path=operator%2F%3A O:amount] | ||
Оператор двоеточия ([http://www.byond.com/members/?command=reference&path=operator%2F%3A :]) в примере выше сообщает компилятору: "Я знаю, что делаю, не обращай внимание на тот факт, что объект не имеет этой переменной. Я сам проверю, что оно работает." Проблема в том, что люди будут использовать ваш код так, как вы никогда не планировали. Это значит, что что-то может заставить 0:amount выдать исключение в виде ошибки Runtime Error. Некоторые переменные, возможно, в конечном итоге потребуется удалить или заменить, и это будет невозможно, когда они используются с object:variable, поскольку компилятор не выдаст ошибку при удалении переменной. Ошибка станет очевидной только после того, как игра будет запущена на реальном сервере, что может привести к ее сбою. Так что '''никогда''' не используйте этот метод. | |||
Вот вам еще несколько источников: | |||
[http://www.byond.com/members/?command=reference&path=proc%2Fistype istype()] proc:<br> | |||
[http://www.byond.com/members/?command=reference&path=proc%2Fisarea isarea(variable)] = istype(variable, /area)<br> | [http://www.byond.com/members/?command=reference&path=proc%2Fisarea isarea(variable)] = istype(variable, /area)<br> | ||
[http://www.byond.com/members/?command=reference&path=proc%2Fisicon isicon(variable)] = istype(variable, /icon)<br> | [http://www.byond.com/members/?command=reference&path=proc%2Fisicon isicon(variable)] = istype(variable, /icon)<br> | ||
Строка 137: | Строка 140: | ||
[http://www.byond.com/members/?command=reference&path=proc%2Fisloc isloc(variable)] = ismob(variable) || isobj(variable) || isturf(variable) || isarea(variable) | [http://www.byond.com/members/?command=reference&path=proc%2Fisloc isloc(variable)] = ismob(variable) || isobj(variable) || isturf(variable) || isarea(variable) | ||
==== | ==== Переключение между типами переменных ==== | ||
Предопределены BYOND:<br> | |||
[http://www.byond.com/members/?command=reference&path=proc%2Fascii2text ascii2text]<br> | [http://www.byond.com/members/?command=reference&path=proc%2Fascii2text ascii2text]<br> | ||
[http://www.byond.com/members/?command=reference&path=proc%2Ffile2text file2text]<br> | [http://www.byond.com/members/?command=reference&path=proc%2Ffile2text file2text]<br> | ||
Строка 151: | Строка 154: | ||
[http://www.byond.com/members/?command=reference&path=proc%2Ftime2text time2text]<br> | [http://www.byond.com/members/?command=reference&path=proc%2Ftime2text time2text]<br> | ||
SS13 | Определены в SS13:<br> | ||
text2dir(direction)<br> | text2dir(direction)<br> | ||
dir2text(direction)<br> | dir2text(direction)<br> | ||
Строка 161: | Строка 164: | ||
angle2text(var/degree)<br> | angle2text(var/degree)<br> | ||
Больше полезных процедур:<br> | |||
[http://code.google.com/p/tgstation13/source/browse/trunk/code/defines/procs/helpers.dm code/defines/procs/helpers.dm]<br> | [http://code.google.com/p/tgstation13/source/browse/trunk/code/defines/procs/helpers.dm code/defines/procs/helpers.dm]<br> | ||
[http://code.google.com/p/tgstation13/source/browse/trunk/code/game/objects/items/helper_procs.dm code/game/objects/items/helper_procs.dm] | [http://code.google.com/p/tgstation13/source/browse/trunk/code/game/objects/items/helper_procs.dm code/game/objects/items/helper_procs.dm] | ||
=== [http://www.byond.com/members/?command=reference&path=proc%2Fif | === [http://www.byond.com/members/?command=reference&path=proc%2Fif IF (ЕСЛИ)] === | ||
If обычно проверяет на истинность условия, если не указано иное. За ложность в других типах переменных принимаются такие значения, как <code>empty</code>, <code>0</code> или отсутствие значения (<code>null</code>). | |||
if(condition) | if(condition) | ||
action_true() | action_true() | ||
Строка 173: | Строка 176: | ||
action_false() | action_false() | ||
==== | ==== Поведение переменных в операторе If ==== | ||
{| | {| | ||
! | !Тип переменной | ||
! | !Ложно когда | ||
! | !Истина когда | ||
|- | |- | ||
!String ( | !String (Text/ASCII) | ||
|"" | |"" или null | ||
| | |Все остальное | ||
|- | |- | ||
!Int | !Int, Real | ||
|0 | |0 или null | ||
| | |Все остальное | ||
|- | |- | ||
!datum, atom | !datum, atom | ||
|null | |null | ||
| | |Все остальное | ||
|} | |} | ||
==== [http://www.byond.com/members/?command=reference&path=operator | ==== [http://www.byond.com/members/?command=reference&path=operator Логические операторы] ==== | ||
Стандарт: | |||
[http://www.byond.com/members/?command=reference&path=operator%2F%21 ! | [http://www.byond.com/members/?command=reference&path=operator%2F%21 ! (НЕ)] //НЕ выражение1 | ||
[http://www.byond.com/members/?command=reference&path=operator%2F%26%26 | [http://www.byond.com/members/?command=reference&path=operator%2F%26%26 && (И)] //выражение1 И выражение2 | ||
[http://www.byond.com/members/?command=reference&path=operator%2F%7C%7C | [http://www.byond.com/members/?command=reference&path=operator%2F%7C%7C || (ИЛИ)] //выражение1 ИЛИ выражение2 | ||
[http://www.byond.com/members/?command=reference&path=operator%2F%3D%3D ==] // | [http://www.byond.com/members/?command=reference&path=operator%2F%3D%3D == (РАВНО)] //выражение1 РАВНО выражению2 | ||
[http://www.byond.com/members/?command=reference&path=operator%2F%21%3D !=] // | [http://www.byond.com/members/?command=reference&path=operator%2F%21%3D != (НЕ РАВНО)] //выражение1 НЕ РАВНО выражению2 | ||
[http://www.byond.com/members/?command=reference&path=operator%2F%26lt%3B <] ([http://www.byond.com/members/?command=reference&path=operator%2F%26lt%3B%3D <=]) // | [http://www.byond.com/members/?command=reference&path=operator%2F%26lt%3B < (МЕНЬШЕ)] ([http://www.byond.com/members/?command=reference&path=operator%2F%26lt%3B%3D <= (НЕ БОЛЬШЕ)]) //1 меньше или равно 2 | ||
[http://www.byond.com/members/?command=reference&path=operator%2F%26gt%3B >] ([http://www.byond.com/members/?command=reference&path=operator%2F%26gt%3B%3D >=]) // | [http://www.byond.com/members/?command=reference&path=operator%2F%26gt%3B > (БОЛЬШЕ)] ([http://www.byond.com/members/?command=reference&path=operator%2F%26gt%3B%3D >= (НЕ МЕНЬШЕ)]) //1 больше или равно 2 | ||
[http://www.byond.com/members/?command=reference&path=operator%2F%26 &] // | [http://www.byond.com/members/?command=reference&path=operator%2F%26 & (Поразрядное И)] //13 & 3 = 1 (1101 & 0011 = 0001) | ||
[http://www.byond.com/members/?command=reference&path=operator%2F%7C ] // | [http://www.byond.com/members/?command=reference&path=operator%2F%7C | (Поразрядное ИЛИ)] //13 | 3 = 15 (1101 | 0011 = 1111) | ||
BYOND не распознает оператор === (эквивалентность). | |||
Больше операторов: [http://www.byond.com/members/?command=reference&path=operator Источник (левое меню)] | |||
=== [http://www.byond.com/members/?command=reference&path=proc%2Fwhile While] === | === [http://www.byond.com/members/?command=reference&path=proc%2Fwhile While] === |
Версия от 16:46, 9 декабря 2022
Похожие руководства: Структура кода SS13 и Руководство по маппингу
Значит, вы знаете, как писать программный код на других языках и хотите краткое руководство для понимания кода SS13? Этот гайд для вас. Вероятно, здесь представлена не вся информация, которую вам следует знать, но для начала её будет достаточно.
Синтаксис
- Точка с запятой в конце строки не является обязательной,
- Циклы, процедуры, объекты, переменные и т.п. блоки определяются отступами (сходство с Python). Примеры:
/obj var i1 i2 i3
идентично коду: (Крайне рекомендуется использовать подобный вариант разметки, для упрощения поиска объявлений переменных и процедур в дальнейшем)
/obj var/i1 var/i2 var/i3
что в свою очередь эквивалентно:
/obj/var/i1 /obj/var/i2 /obj/var/i3
- Руководство использует термин объект для любых определенных типов (см. Типы переменных), и obj для производных
atom/obj
, все из которых являются объектами, которые могут быть размещены на игровой карте. - Руководство использует термин 'подконтрольный ИИ' для описания поведения, связанного с игроком в роли ИИ, контролирующего предмет. Термин 'подконтрольный игре' используется, отсылаясь к поведению, которое определяет сам скрипт. (Существ с подобным поведением обычно называют существами, подконтрольными ИИ, или NPC)
- Все унаследовано от родительских объектов. Если переменная определена в
/obj/item
, её не нужно будет (на самом деле, нельзя) определять в/obj/item/weapon
.
Переменные (Источник)
Переменные - это база. В BYOND переменные общие, не существует большой разницы при определении строковых, числовых, булевых и т.д. (Как в PHP)
Предопределенные переменные (Источник)
В BYOND существует большое количество предопределенных переменных, самые основные из них:
- src - эквивалентна объекту, содержащему процедуру или переменную. При определении принимает тот же тип, что и этот объект. (Аналогично
this
из Java или C++) - usr - переменная сущности (моба) (
var/mob/usr
), содержит сущность игрока, исполнившего текущий оператор или чье действие в конечном счете вызвало текущую процедуру. Хорошее правило из практики: никогда не помещатьusr
в процедуру. Еслиsrc
не будет верным выбором, лучше отправить другой аргумент в процедуру с необходимой информацией. - args - список аргументов, принятых в процедуре или операторе.
- vars - список переменных-объектов. Если использовать имя переменной в качестве индекса списка, возвращает значение этой переменной.
Больше переменных описано здесь: Предназначение основных переменных в коде SS13
Определение переменных
Базовое определение
var/j var/i = 4 var/a, b, c
Комплексное определение
Основной синтаксис: var/type/variable_name = value
(из источника)
Примеры:
var/obj/item/I = new/obj/item I.name = "Some item"
Определение блока данных (datum) и объявление переменной этого типа данных (test_datum):
datum/test_datum var/test_variable = 0 //объявляем переменную test_variable proc/set_as(var/i) //объявление процедуры в рамках test_datum test_variable = i //присваиваем test_variable значение из аргумента var/datum/test_datum/TD = new/datum/test_datum //TD будет указателем на блок данных типа test_datum TD.test_variable = 4 //Byond не знает о приватных переменных, так что можно присваивать им значение таким образом world << TD.test_variable //вернет 4 всем подключенным пользователям TD.set_as(10) //Вызовет процедуру set_as в блоке данных TD с аргументом 10 TD.test_variable //вернет 10 всем подключенным пользователям
Битовый флаг
Битовые флаги (Bitflags) - это переменные, использующие биты вместо чисел для определения условий. Битовые операторы: & (поразрядное И) и | (Поразрядное ИЛИ). Данные операторы используют двоичную систему счисления для определения результата. Таким образом, 13 & 3 вернет 1. (1101 & 0011 = 0001) и 13 | 3 = 15 (1101 | 0011 = 1111) (см. #IF (ЕСЛИ))
Типы переменных
- datum - обычный тип объекта (классы из Java)
- atom - атомарные переменные, превращаются в obj, turf, mob и area
- turf - плитки, составляющие полов, стен и космоса в SS13
- area - зоны, сгруппированные локации. Объединяют множество turf с похожими свойствами. Определяют электроснабжение, атмосферу и т.п.
- mob - живое существо, контролируемое игрой или игроком.
- obj - объекты, которые могут быть размещены на карте.
- client - объект клиента, создаваемый при подключении игрока
- list - список элементов. Первый элемент списка L определяется как L[1]
- world - переменная, в которой могут быть определены глобальные переменные игрового мира. Переменные в world содержат все атомарные переменные, присутствующие в игровом мире.
Вывод сообщений
Самым простым способом вывода сообщений является использование оператора <<.
world << "Hello World!" //Выводит сообщение всем клиентам, подключенным к миру. usr << "Hello usr" //Выводит сообщение только для пользователя, который вызвал процедуру с данным оператором.
Вывод значений переменных
var/s1 = "Привет" var/s2 = "Мир" var/i = 2011 var/j = 2022 world << "[s1] [s2], руководство написано в [i], переведено в [j]" //Возвращает "Привет Мир, руководство написано в 2011, переведено в 2022"
Определение типов переменных в коде
Процедура istype() вам пригодится.
Пример:
var/obj/item/weapon/W = new/obj/item/weapon/baton if(istype(W,/obj/item/weapon/baton)) world << "Это - baton!"
Второй аргумент необязателен, если опущен, переменная будет проверена на соответствие объявленному типу:
var/obj/item/weapon/W = new/obj/item/weapon/baton if(istype(W)) world << "Это - weapon!"
Стандартный код для получения аргументов из переменных, которые имеют тип, являющийся подклассом типа, с которым их обрабатывает текущая процедура (см. пример любой процедуры Attackby()). Обратите внимание, что приведенный ниже пример относится к процедуре, которая определена глобально и не привязана к объекту. Не имеет смысла делать это так, но это работает в рамках примера. Объекты /obj не имеют переменной 'amount', она определена в /obj/item/stack (как показано в упрощенном определении классов ниже. Также обратите внимание, где var/ используется, а где нет).
/obj var/name = "Object" /obj/item name = "Item" /obj/item/stack name = "Stack" var/amount = 50 proc/get_amount(var/obj/O) if(istype(O,/obj/item/stack)) var/obj/item/stack/S = O return S.amount
Другой способ проделать такое. Он существует исключительно для демонстрации.
proc/get_aount(var/obj/S) if(istype(O,/obj/item/stack)) return O:amount
Оператор двоеточия (:) в примере выше сообщает компилятору: "Я знаю, что делаю, не обращай внимание на тот факт, что объект не имеет этой переменной. Я сам проверю, что оно работает." Проблема в том, что люди будут использовать ваш код так, как вы никогда не планировали. Это значит, что что-то может заставить 0:amount выдать исключение в виде ошибки Runtime Error. Некоторые переменные, возможно, в конечном итоге потребуется удалить или заменить, и это будет невозможно, когда они используются с object:variable, поскольку компилятор не выдаст ошибку при удалении переменной. Ошибка станет очевидной только после того, как игра будет запущена на реальном сервере, что может привести к ее сбою. Так что никогда не используйте этот метод.
Вот вам еще несколько источников:
istype() proc:
isarea(variable) = istype(variable, /area)
isicon(variable) = istype(variable, /icon)
ismob(variable) = istype(variable, /mob)
isobj(variable) = istype(variable, /obj)
isturf(variable) = istype(variable, /turf)
isloc(variable) = ismob(variable) || isobj(variable) || isturf(variable) || isarea(variable)
Переключение между типами переменных
Предопределены BYOND:
ascii2text
file2text
list2params
num2text
params2list
text2ascii
text2file
text2num
text2path
time2text
Определены в SS13:
text2dir(direction)
dir2text(direction)
dd_file2list(file_path, separator)
dd_text2list(text, separator, var/list/withinList)
dd_text2List(text, separator, var/list/withinList)
dd_list2text(var/list/the_list, separator)
angle2dir(var/degree)
angle2text(var/degree)
Больше полезных процедур:
code/defines/procs/helpers.dm
code/game/objects/items/helper_procs.dm
IF (ЕСЛИ)
If обычно проверяет на истинность условия, если не указано иное. За ложность в других типах переменных принимаются такие значения, как empty
, 0
или отсутствие значения (null
).
if(condition) action_true() else action_false()
Поведение переменных в операторе If
Тип переменной | Ложно когда | Истина когда |
---|---|---|
String (Text/ASCII) | "" или null | Все остальное |
Int, Real | 0 или null | Все остальное |
datum, atom | null | Все остальное |
Логические операторы
Стандарт:
! (НЕ) //НЕ выражение1 && (И) //выражение1 И выражение2 || (ИЛИ) //выражение1 ИЛИ выражение2 == (РАВНО) //выражение1 РАВНО выражению2 != (НЕ РАВНО) //выражение1 НЕ РАВНО выражению2 < (МЕНЬШЕ) (<= (НЕ БОЛЬШЕ)) //1 меньше или равно 2 > (БОЛЬШЕ) (>= (НЕ МЕНЬШЕ)) //1 больше или равно 2 & (Поразрядное И) //13 & 3 = 1 (1101 & 0011 = 0001) | (Поразрядное ИЛИ) //13 | 3 = 15 (1101 | 0011 = 1111)
BYOND не распознает оператор === (эквивалентность).
Больше операторов: Источник (левое меню)
While
Byond will cancel a loop if it reaches a certain number of iteration and give a runtime error out of fear of infinite loops. Same applies for recursions. Same as anywhere else
while(condition) action1()
All loops understand the continue and break commands
For
All loops understand the continue and break commands
For combines the for loop and foreach loop:
For loop
for(var/i = 1; i <= 10; i++) world << i //Will write (each in a new line) 1 2 3 4 5 6 7 8 9 10
For each
for(var/obj/item/weapon/baton/B in world) //will iterate through world.contents (which contains all atoms in the world) and only pick those which are of the given type (/obj/item/weapon/baton) B.name = "Smelly baton" //Will apply the new name to the baton in the current iteration loop
Do - While
The Do while operator is not commonly used in SS13 code, Byond does support it tho.
var/i = 3 do world << i-- while(i)
All loops understand the continue and break commands
Defining objects
Doesn't matter if you want a datum or atom, the definition of objects is the same and simple:
/obj/item/weapon/item1 //will nmake a new object of type obj. var/item_property = 5 //Will define a new variable type for all item1 objs name = "Testing Item" //The name var is already defined in parent objects so it is not defined here, but only assigned a new valie. /obj/item/weapon/item1/New() //Constructor proc ..() //should always be present in New() procs, see ..() for more information item_property = 3 //An action that is performed in the object constructor.
Procs (Methods, functions, procedures)
You're used to the standards of methods, functions and procedures, right? Well procs ignore some aspects of these. They can best be compared to Java methods, as they're tied to specific objects. They cannot be defined as static, private, public, etc. tho. You can write static methods, however the compiler will not restrict you from calling them in a non-static way or environment. Same applies for non-static methods.
proc/proc_name(var/argument1, var/argument2) world << "[argument1] [argument2]"
The above would declare a global proc. If you wish to tie it to a certain level
..()
This is the same as super() in Java. It calls the parent object type's proc with the same name and same arguments.
Example:
/obj/item name = "Item" /obj/item/New() //New() is the proc that gets called whenever a new object of this type is created. A constructor if you will. src.name = "It's an item!" /obj/item/stack name = "Stack" /obj/item/stack/New() src.name = "It's a stack!" ..()
If you have the code from the example above and create a new object of type /obj/item/stack, it will first make the item in the game world with the name "Stack", because it's defined to be that by default. Then the New() proc will be called immedietally after. This will change the name to "It's a Stack!" but the call of the parent type's New() proc with the ..() command will then set it to "It's an item!". So in the end, the new object will be called "It's an item!". The ..() command is however very important in many cases as some things are defined only in the common parent's New() procs. In Del(), the proc which gets called prior to an object's deletion, it requires the code to get to the root Del() proc to even delete it. See examples of Del() in the code.
Important procs
New()
This proc is called whenever a new instance of the object is created. It can have arguments if needed. It should call ..() where applicable so that parent constructors can be applied.
If you wish to create a New() proc for atoms with custom arguments, ensure the first argument is for the object's location. Example:
obj/item/weapon/my_item/New(var/location, var/i) ..() //Whatever else you need to do
To make a general object use
new /datum/test_datum
To make an atom (which usually has a locaiton)
new /obj/item/weapon(src.loc)
For the custom example above, the code to create a new such object would be: The 5 is just an example of a value which could be assigned to the var/i in the constructor.
new /obj/item/weapon/my_item(src.loc, 5)
Where src is the proc owner, which contains the line above. src.loc is the locaiton of the src object.
Del()
This proc gets called before an object's delection. It MUST call ..() at the end as the actual deletion is done in the root Del() proc.
An object is deleted by using the del(O) proc with O being the object to be deleted.
attack_hand(mob/M as mob)
Whenever a user (M) clicks on the object with an empty active hand
attack_paw(mob/M as mob)
Whenever a monkey (M) clicks the object with an empty active hand
If a custom attack_paw(mob/user) proc is not written for an atom, it defaults to calling attack_hand(user)
attack_ai(mob/user)
Whenever an AI or cyborg clicks the object with an empty active hand
If a custom attack_ai(mob/user) proc is not written for an atom, it defaults to calling attack_hand(user)
attack(mob/M as mob, mob/user as mob)
When the object is used to attack mob M by mob user
attackby(obj/item/W, mob/user)
When the object is being attacked by user with W (Example: If you click on wires with wirecutters)
ex_act(severity)
How the item reacts to explosions. Severity can either be 1, 2 or 3 with 1 being the most destructive.
blob_act()
How the item reacts to a blob (magma) attack
emp_act(severity)
How the item reacts to an EMP. Severity can either be 1 or 2 with 1 being the more powerful EMP surge.
Topic(href, href_list)
This one's called when you click a link in a pop-up window. Like when you increase the output of SMES cells. The href_list variable is the important one as it's a parsed version of the arguments you add into a link. To make a link in the pop-up window, add the following line to the text you display (dat in the example):
dat += text("<A href='?src=\ref[src];select=[i]'>[src.name]</a><br>")
Check the code for more examples of this.
process()
This gets called for all objects on every tick. If possible, avoid it as it's processor heavy, but for some things it just can't be avoided.
SS13 common variable meanings
Datum
Datums have the smallest number of pre-defined variables. These are present in all objects in the game:
type //The type of an object. If your object is of type /obj/item/weapon/shovel writing the following: new src.type(src.loc) will make another shovel in the same tile. parent_type //Parent type of /obj/item/weapon/shovel is /obj/item/weapon... seems streight-foward enough. tag //The tag is used to help you identify things when using several instances. It has to be set manually for each instance tho. Lazy coders and mappers resulted in not many tags being used. Instances in the map editor are sorted by tag. vars //List of object vars the datum has defined
Atom
These variables are shared by all areas, mobs, objs and turfs.
contents //List of contents. Closets store their contents in this var as do all storage items. All the items on a turf are in the turf's contents var. density //If density is at 0, you can walk over the object, if it's set to 1, you can't. desc //Description. When you right-click and examine an object, this will show under the name. dir //Object direction. Sprites have a direction variable which can have 8 'legal' states. gender //not used icon //The dmi file where the sprite is saved. Must be written in single quotations (Example: 'items.dmi') icon_state //The name of the sprite in the dmi file. If it's not a valid name or is left blank, the sprite without a name in the dmi file will be used. If such a sprite doesn't exist it will default to being blank. invisibility //Invisibility is used to determine what you can and what you can't see. Check the code or wait for someone who knows how exactly this works to write it here. infra_luminosity //Only mecha use this underlays //List of images (see image() proc) which are underlayed under the current sprite overlays //List of images (see image() proc) which are overlayed over the current sprite loc //Contains a reference to the turf file where the object currently is. layer //A numerical variable which determins how objects are layered. Tables with a layer of 2.8 are always under most items which have a layer of 3.0. Layers go up to 20, which is reserved for HUD items. luminosity //How much the item will glow. Note that the picking up and dropping of luminous items needs to be specially handled. See flashlight code for an example. mouse_over_pointer //not used mouse_drag_pointer //(almost) not used mouse_drop_pointer //not used mouse_drop_zone //not used mouse_opacity //Used in a few places. Check the description in the reference page name //The name of the object which is displayed when you right click the object and in the bottom left of the screen when you hover your mouse over it. opacity //Whether you can see through/past it (glass, floor) when set to 0 or whether you can't (walls, mecha) when set to 1. pixel_x //How many pixels in the x direction should the sprite be offset from the starting set. See the APC's New() proc for an example and how fire alarms are defined on the map. pixel_x = -5 will move it 5 pixels to the left and pixel_x = 5 will move it 5 pixels to the right pixel_y //Same as pixel_y but in the y direction. Positive values move it to the north, negative to the south. pixel_z //Used in isometric maps, so it's not used in SS13 suffix //Rarely used. See the reference page for more information text //How to represent the object on text clients. Not used. type //The type of the object vars //See Datum above verbs //The verbs you can use with the item. Verbs are the options in the right click menu. x //X position, read only. Set the loc variable to move it or use the inbulit functions. y //Y position, read only. z //Z position (Which z-level it's on), read only.
Area
var/requires_power = 1 //Areas which are to work without an APC (Such as centcom areas) should have this at 0. All other areas should have it at 1. var/music = null //Music to be played when you enter the area. luminosity = 0 //Areas which should be lit at all times (such as space and centcom) should have this at 1 as well as the sd_lighting var at 0 var/sd_lighting = 0 //This var determines whether dynamic lighting is to be calculated for the area's tiles. Turn this to off only for areas which have the luminosity var set to 1
Most other variables exist only for technical reasons and should not be messed with unless done through existing procs, they are defined in:
code/game/area/Space Station 13 areas.dm
Mob
There is a huge amount of variables for mobs. Take a look at the following files:
code/defines/mob/mob.dm code/defines/mob/dead/observer.dm code/defines/mob/living/living.dm code/defines/mob/living/carbon/carbon.dm code/defines/mob/living/carbon/human.dm code/defines/mob/living/carbon/monkey.dm code/defines/mob/living/silicon/silicon.dm code/defines/mob/living/silicon/ai.dm code/defines/mob/living/silicon/robot.dm
There are also additional files for aliens, larva, facehuggers and more there, but the files above will have most of the variables you might need.
Obj
var/m_amt = 0 // How much metal the item has. Used to determine how much metal you get when feeding it into an autolathe and how much it costs to produce it at the lathe var/g_amt = 0 // How much glass the item has. Used to determine how much glass you get when feeding it into an autolathe and how much it costs to produce it at the lathe var/w_amt = 0 // waster amounts. Not used var/origin_tech = null //Used by R&D to determine what research bonuses it grants. See examples in item definitions in code. var/reliability = 100 //Used by SOME devices to determine how reliable they are. The number represents the percentual chance for them to work properly. var/unacidable = 0 //universal "unacidabliness" var, objects with this set to 1 cannot be destroyed by acids. var/throwforce = 0 //The amount of damage applies to a target when they're hit by the item.
More variables are defined in:
code/defines/obj.dm
Item
Items are objs which can be picked up. They're divided into several categories according to their function.
/obj/item is defined in the following file:
code/defines/obj.dm
It adds the following variables (Look at the file for more, but these are the more important ones):
var/force = null //This determins how much damage the target takes when they're attacked by the item in hand. Small items usually have it at 0, medium ones between 5 and 10, rare and powerful items around 10-15 and two-handed items at 15 and more. Syndicate items have it even higher at 40 and more. var/item_state = null //This it the var that determines which sprite will be used for the item from icons/mob/items_lefthand.dmi and items_righthand.dmi. var/damtype = "brute" //Determines what damage type the item produces. var/health = null //Some items use this to determine when they'll break from use or damage. Not common tho. var/hitsound = null //Sound that's played when you hit something with the item. Not commonly used. var/w_class = 3.0 //Weight class. // w_class = 1 means it's an item that can fit in a pocket (diskette, pen, cigarette packet) // w_class = 2 means the item can't fit in pockets but can fit in a box (clipboard, analyzer, cleaner) // w_class = 3 means the item can't fit in a box but can fit in backpacks (box, rods, metal) // w_class = 4 means the item can't even fit in a backpack (packpack, pickaxe, fireaxe) // w_class = 5 is used but not for weight classes. var/wielded = 0 //Used for double-handed items which can be carried in one hand but needs to be wielded by two hands before they can be used. This is determined by code when wielding and unwielding. All items should start with this at 0. var/twohanded = 0 ///Set this to 1 if your item is two-handed. flags = FPRINT | TABLEPASS //Flags
Machinery
Defined in:
code/defines/obj/machinery.dm
Machinery are objs which cannot be picked up and generally require power to operate. They have the following vars defined for all of them:
var/use_power = 0 //Determines if and how much power the machine will use each tick. //use_power = 0 - no power is used //use_power = 1 - idle power is used //use_power = 2 - active power is used var/idle_power_usage = 0 //How many watts of power the machine will use each tick when use_power is set to 1 var/active_power_usage = 0 //How many watts of power the machine will use each tick when use_power is set to 2 var/power_channel = EQUIP //Determines which APC power category the device falls under. EQUIP, ENVIRON or LIGHT var/list/component_parts = null //A list of parts needed to construct the machine from a machine frame.
Turf
var/intact = 1 //This determines if the turf will hide pipes, cable and such. Set to 1 to hide and to 0 to not hide them. Only pipes and wire with level set to 1 will be hidden. Set their level var to 2 to keep them from being hidden. var/blocks_air = 0 //Determines if the turf prevents air from passing (walls) if set to 1.
Other variables exist but they're tied to atmospherics code which is not to be touched as whenever anything is changed in it it results in a million things breaking.
code/defines/turf.dm
Simulated
Simulated floors are tiles which simulate air movement and temperature. The station is made entirely from these while centcom is made from unsimulated floors to prevent massive and unneeded lag.
var/wet = 0 //If this it a positive number, it is wet and you'll slip on it if you run. var/thermite = 0 //Will be set to 1 when thermite is poured on it.
Simulated floors
var/icon_regular_floor = "floor" //Determines what icon the steel version of the floor should have. Determined at floor creation (New() proc). If the icon_state of the floor at that point is one from the global icons_to_ignore_at_floor_init var, then this variable is assigned the value "floor". The icons_to_ignore_at_floor_init list contains broken, plating, burnt and non-steel icon_states from icons/turf/floors.dmi heat_capacity = 10000 //When a fire (hotspot) on the tile exceeds this number, the floor has a chance of melting. The more the number is exceeded, the higher the chance of melting. var/broken = 0 //This mostly only determins if you'll get the tile back when you use the crowbar var/burnt = 0 //This mostly only determins if you'll get the tile back when you use the crowbar var/obj/item/stack/tile/floor_tile = new/obj/item/stack/tile/steel //What floor tile is on the tile
Simulated floors are defined in:
code/game/turf.dm
Simulated walls
Doesn't really contain any special new variables.
Defined in:
code/defines/turf.dm
Как внести свой вклад? | |
---|---|
Общее | Руководство по разработке |
Сервер | Настройка базы данных, Запуск локального сервера |
Код | Структура кода SS13, SS13 для опытных программистов, Форматирование текста, Как делать перевод игры |
Маппинг | Руководство по маппингу |
Спрайтинг | Руководство по спрайтингу |
Вики | Руководство по редактированию вики |