Итак, приступим.
Для начала прочитаем небольшой гайд, раскрывающий основные функции.
Внимание! Это руководство использует весьма примитивные средства разработки и термины. Опытным кодерам – просьба не ругать меня за неточные определения. Это руководство предназначено для новичков. Оставшиеся... не читайте это, серьезно.
DreamMaker
Программа, нужная тебе для создания и редактирования кода, для маппинга. Данная программа состоит из шести главных компонентов – древо файлов, объектное дерево, редактор текста, редактор спрайтов, редактор карт и панель ошибок.
Древо файлов
Древо файлов может быть вызвано с помощью вкладки "File" в левой вертикальной панели. Оно отображает фаилы, составляющие код, в порядке сортировки по папкам. Двойной щелчок по любому фаилу откроет его в нужном редакторе. Если ты добавляешь новый фаил в реестр (в Шindows Explorer), нажми кнопку "Refresh" для обновления данного списка. Отметки рядом с фаилами показывают то, будут ли использованы фаилы в компиляции кода. Распространенная ошибка – забыть поставить отметку.
Древо объектов
Что же это такое, блджад? Так я тебе и сказал. Сейчас тебе достаточно знать, что это список объектов, возможных к размещению на карте. Они упорядочены в иерархию. Это я тоже объясню позже, дорогой новокодер. Кнопка "Update" внизу экрана обновит древо новыми объектами, если они были добавлены в отмеченный фаил .dm, так то.
Редактор текста
Это, кодеры мои, ваша альфа и омега, ваш хлеб и вода. Редактор активируется, когда ты открываешь фаил с расширением ".dm". Суть – написание и редактирование игрового кода. Ничего сложного, да?
Редактор спрайтов
Предназначен для изменения и создания игровых иконок. Активируется при открытии фаила формата "dmi". Он показывает список всех спрайтов (часто называемых icon states), находящихся в фаиле. Правый клик где - либо вызовет опцию создание нового спрайта или анимации. Иконка - статичная картинка. В анимации же спрайт может иметь восемь различных направлений (называемых на пиндосском dirs) или быть анимированным. Анимация может иметь одно 1 (Юг), 4 (С/Ю/В/З) или восемь направлений. Также запомните, что фаил формата .dmi может содержать в себе спрайты только одного и того же размера. Из-за, к примеру, сингулярности, которая ЖРЕТ ВСЕХ И ВСЯ И РАСТЕТ ОМНОМНОМ часто требуются отдельные ".dmi".
Редактор карт
Обычно открывается при старте, или при открытии ".dmm" фаила -- фаила карты. А теперь шокирующая правда – редактор карты используется для создания и редактирования карты. По умолчанию, данный редактор показывает 4 основные группы: разметка территории (area), существа (mob), объекты (object) и турфы (turf). Для выбора критериев отображаемого нажми вкладку "Layers" в самом верху панели инструментов и выбери 'Only show selectable layers', затем выбери нужные тебе слои. Замечу, что карта не будет показана с ошибками в коде. Исправь их. Или ты совсем... Впрочем, чего это я.
Панель вывода ошибок
Текстовая панель внизу экрана DreamMaker'a, панель ошибок существует, чтобы услужить вам в сообщении ошибок в компиляции.
Тут, собственно, заканчивается раздел о составляющих, и мы приступаем к самому коду.
Компиляция и запуск
Что бы скомпилировать обновленный код без запуска, выберите вкладку 'build' в самом верху экрана и нажмите 'compile'. Для компиляции и запуска нажмите 'compile and run'.
Составляющие кода
Переменные
Ссылка: http://www.byond.com...erence&path=var
Переменные предназначены для хранения данных. Создаются таким образом: (создание переменной без определенной информации) var/i
Чтобы задать переменной значение, следует сделать вот так:
var/i = 5
Или
var/i = "Hello World"
Как только переменная была задана, ты уже не сможешь задать другую с таким же названием:
var/i
i = 2
i = 6
i = 12
List
Список, он же list.
Ссылкота: http://www.byond.com...rence&path=list
Список может определяться, как любое из древ, но специальные переменные ассоциируются именно со списком. Доступен лишь при первом назначении переменной.
var/list/a
var/a[9]
var/a = list()
Другие типы переменных
Если ты хочешь схоронить монету в объекторной переменной и использовать операции или переменные, тебе нужно определить переменную, в которой ты хранишь монету. Второй пример создает переменную D, заполняя ее новой монетой!
var/obj/item/weapon/coin/C
var/obj/item/weapon/coin/D = new/var/obj/item/weapon/coin(src)
Встроенные переменные
Переменные, встроенные в BYOND и неизменяемые в процессе создания кода:
Atom vars http://www.byond.com...e&path=atom/var
Client vars http://www.byond.com...path=client/var
Datum vars http://www.byond.com...&path=datum/var
Mob vars http://www.byond.com...ce&path=mob/var
Переменные направления (dir vars)
Ссылка: http://www.byond.com...th=atom/var/dir
Север: 1
Юг: 2
Восток: 4
Запад: 8
Северо-восток: 5 (1 + 4)
Юго-восток: 6 (2 + 4)
Северо-запад: 9 (1 + 8)
Юго-запад: 10 (2 + 8)
Нумерованы они так потому, что dir использует числовой тип. Определяется он в бинарной системе, так что...
0001 -- Север
0010 -- Юг
0100 -- Восток
1000 -- Запад
Соединение этой четвёрки добавляет Северо-восток (0101), Северо-запад (1001), Юго-восток (0110) и Юго-запад(1010). Другие комбинации нужны для... Эээ... Ну, в общем, они существуют, но нужны ли они? (Востоко-запад(1100), северо-юг (0011), северо-востоко-запад(1101), тысячи их!). Впрочем, в коде можно найти достойные образчики.
Переменные типа atom.
Применимы ко всем объектам типа /obj, /turf, /area, /mob.
Contents: Список объектов, введенных в другой объект. (Баллоны с плазмой в коллекторах, руда в печи, etc.)
Density: 0/1 - 0 означает, что существо может пройти сквозь (или над), 1 -- что не может.
Desc: string - Описание, которое показывается при "examine".
Dir: 1-10 - направление объекта.
Icon: .dmi фаил, содержащий иконку.
Icon_state: Название спрайта из прошлого пункта.
Overlays: Список спрайтов, которые находятся поверх исходного.
Layer: Если два объекта находятся на одном тайле и у одного номер слоя выше, чем у другого, объект с наибольшим номером будет показываться поверх другого.
Loc: Координаты X, Y, Z расположения предмета.
Luminosity: Как долго будет светиться?
Name: Название. Высвечивается при наведении курсора на объект. Нуфф сэид.
Opacity: Можно ли видеть сквозь это?
Pixel_x, pixel_y: Настраиваемо, если предмет на карте нужно передвинуть на пару пикселей по тайлу. Используется с APC, Консолями, Пожарными тревогами, etc.
Type: Type -- путь к объекту. Монета будет иметь такую переменную:
/obj/item/weapon/coin
Включенные инструкции
Гайды по включенным инструкциям (proc-s) доступны для ознакомления по следующим ссылкам:
Area procs http://www.byond.com...&path=area/proc
Mob procs http://www.byond.com...e&path=mob/proc
Obj procs http://www.byond.com...e&path=obj/proc
Turf procs http://www.byond.com...e&path=obj/proc
Операторы условий.
Условные операторы формулируют, как исполняется код, зависящий от условий. Самый обычный оператор условий – условие оператора IF.
= против ==
var/a
a = 14
if (a == 14)
world << "A has the value [a]"
else
world << "A is not 14"
Как в примере выше, одиночный = означает то, что вы назначаете переменной справа значение переменной слева. В примере выше, переменной присвоено значение 14 (a = 14)
Двойной == используется для сравнения двух значений. Обычно он используется для условий. В примере выше видно, что мы сравнили переменную a с 14 (a == 14). Это определяет, как сработает оператор if.
If statement
Ссылкота: http://www.byond.com...ce&path=proc/if
Пример оператора If. Оператор If проверяет верность утверждения в скобках (в примере выше A == 14). Если оно верно, исполнение кода продолжится (в случае выше: world << "A has the value [a]"). В другом случае, если утверждение не верно, программа будет использовать код после оператора else. Например, если a не является 14, то будет использовано world << "A is not 14"
Операции сопоставления включают в себя:
== Равно
!= Не равно
< Меньше, чем
> Больше, чем
<= Меньше или равно
>= Больше или равно
Switch-case statement
Ссылкота: http://www.byond.com...ath=proc/switch
Loops (Циклы)
While
Ссылка: http://www.byond.com...path=proc/while
For
Ccылку в студию: http://www.byond.com...h=proc/for/loop
For (foreach)
Ссылка: http://www.byond.com...h=proc/for/list
Procs (Процессы)
Ссылочка :3 http://www.byond.com...rence&path=proc
Что такое "Объект"?
SS13 написан в среде Byond, являющейся объектно-ориентированной. Заметь, что под объектом я не имею в виду предмет или механизм в игре. Сейчас я расскажу немного об объектах..
Объектом будет любой определенный путь в игре, например:
/obj/item/weapon/sword
/turf/simulated/floor
/area/
/atom/
Объект состоит из переменных и операций.
Пример:
/turf/simulated/gold_spot
var/spawned_gold = 0
name = "Gold Area"
desc = "This plot may have spawned gold!"
/turf/simulated/gold_spot/proc/spawn_gold()
if(prob(50))
new/obj/item/stack/sheet/gold(src)
spawned_gold = 1
/turf/simulated/gold_spot/New()
..()
spawn_gold()
Иерархия и другая khooeta
Объекты наследуют все переменные и операции своих "родителей". Это значит, что объект, обозначенный как /obj/item/weapon/storage/box, имеет все переменные /obj/item/weapon/storage, /obj/item/weapon, /obj/item, /obj и так же /atom, но об этом мы потолкуем попозже. Некоторые операции обозначены для всех объектов, что вы можете увидеть здесь. В примере выше, New() является этапом операции, которая наследуется от "материнского" объекта. Вот почему у New() нет префикса операции! – потому что он уже задан материнским объектом.
Когда мы определяем два объекта...
/turf/simulated/gold_spot/plot1
/turf/simulated/gold_spot/plot2
...мы просто определяем два "дочерних" объекта /turf/simulated/gold_spot, и они наследуют все переменные и операции, которые включает в себя /turf/simulated/gold_spot, которые он наследует от (/turf/simulated).
..()
Это то, что ты, скорее всего, часто встретишь в коде. На других языках программирования обычно это называется super() – хрень, вызывающая операцию материнского объекта с тем же именем. В отличие от других языков, данный оператор не используется автоматически, если не добавлен. Эти общие определения обычно обеспечивают правильное управление вещами.
Area, Mob, Obj and Turf organization
/datum
/atom
/area – Все данные объекты нужны для разметки карты
APC's power coverage, lighting, atmos, etc.
/mob
/dead – призраки
/living
/carbon – люди и обезьяны
/silicon – ИИ и киборги
/obj
/effect – Триггеры, декали и ландмарки
/item
/clothing – Вещи
obj/item/weapon/storage
/devices – Устройства
/stack – Складываемые предметы
/weapons – -Большинство подбираемых предметов
/machinery – механизмы, использующие энергию, работающие каждый тик.
/structure – объекты, которые не работают каждый тик
windows, grilles, bookcases etc.
/turf
/simulated
/floor – пол с воздухом
/airless – пол без газов
/plating – покрытие
/airless – безвоздушное покрытие
/wall – стены
/r-wall – укрепленные стены
/space – космос
/unsimulated – места без симуляции расчета газов.
П.С. Гайд сделан моим другом, он не мой. Далее я сделаю более подробный гайд, дающий практику и раскрывающий большую часть кода.
Автор:Mr.Smoke Отредактировано:Hank667
[font='Lucida Grande', ', Arial, tahoma, verdana, sans-serif} ']Урок первый. Вступление.[/font]
Часть 1.
Начнем с самого простого- создания оружия.Оружие бывает нескольких типов: Лазерное, энергитическое и т.д. У каждого типа есть свои свойства. Вперед. Я использую немного модернизированный билд Блэка, но пути должны быть одинаковыми. Переходим в /obj/item/weapon/gun/projectile/deagle/obj/item/weapon/gun/projectile/deagle
name = "\improper Desert Eagle"
desc = "A robust handgun that uses .50 AE ammo"
icon_state = "deagle"
force = 14.0
max_shells = 7
caliber = ".50"
ammo_type ="/obj/item/ammo_casing/a50"
"/obj/item/weapon/gun/projectile/deagle"- Путь к обьекту;
"name = "\improper Desert Eagle"- Имя обьекта;
"desc = "A robust handgun that uses .50 AE ammo"- Данное сообщение будет выводится при нажатии "Examine"
"icon_state = "deagle"- Спрайт нашего обьекта;
"force = 14.0"- Урон при выстреле, как я понял;
"max_shells = 7"- Максимальное кол-во патронов;
"caliber = ".50"- Калибр оружия (Есть ".38",".357",".50"...)
"ammo_type ="/obj/item/ammo_casing/a50"- Это путь гильзам, следовательно, будет спавнится такой вид гильз.
Ну, приступим к небольшому изменению.
/obj/item/weapon/gun/projectile/deagle
name = "Fuccken Deagle"
desc = "Its a Deagle, baby"
icon_state = "deagle"
force = 45.0
max_shells = 45
caliber = ".38"
ammo_type ="/obj/item/ammo_casing/a50"
Вот и подходит к концу первый урок. Теперь мы поняли, какие функции есть у оружия и как они, собственно, используются.
Это всего-лишь начало, да слишком просто пока. Если сделал ошибки, то исправьте. Если хотите определенный урок- говорите.
Второй урок. Первая часть.
Мы продолжаем. Сегодня разберем оружие синдиката, вперед. Начнем с пожирателя энергии, пожалуй. Переходим по пути /obj/item/device/powersink.
Видим следующий код:
/obj/item/device/powersink
desc = "A nulling power sink which drains energy from electrical systems."
name = "power sink"
icon_state = "powersink0"
item_state = "electronic"
w_class = 4.0
flags = FPRINT | TABLEPASS | CONDUCT
throwforce = 5
throw_speed = 1
throw_range = 2
m_amt = 750
w_amt = 750
origin_tech = "powerstorage=3;syndicate=5"
var/drain_rate = 600000 // amount of power to drain per tick
var/power_drained = 0 // has drained this much power
var/max_power = 1e8 // maximum power that can be drained before exploding
var/mode = 0 // 0 = off, 1=clamped (off), 2=operating
Тут довольно сложно, если честно. Видим переменные. Для вашего понимания будем разбирать по порядку.
"throwforce = 5"- урон при бросании;
"throw_speed = 1"- скорость бросания;
"throw_range = 2"- Радиус бросания;
"origin_tech = "powerstorage=3;syndicate=5"- Уровень иследований при использовании данного оборудования в деструктор;
А вот и переменные.
"var/drain_rate = 600000"- Количество энергии, которую будет поглощать мгновенно (600000- пару секунд и энергии нет, 700000- мгновенное отключение);
"var/power_drained = 0 "- количество уже поглощенной энергии;
"var/max_power = 1e8"- Максимальное количество энергии, довольно большое. В некоторых билдах уменьшено.
"var/mode = 0"- 0- не закреплен, не включен, 1- закреплен, 2- включен.
Переходим далее. Далее большой код, осторожно.
var/obj/structure/cable/attached // the attached cable
attackby(var/obj/item/I, var/mob/user)
if(istype(I, /obj/item/weapon/screwdriver))
if(mode == 0)
var/turf/T = loc
if(isturf(T) && !T.intact)
attached = locate() in T
if(!attached)
user << "No exposed cable here to attach to."
return
else
anchored = 1
mode = 1
user << "You attach the device to the cable."
for(var/mob/M in viewers(user))
if(M == user) continue
M << "[user] attaches the power sink to the cable."
"var/obj/structure/cable/attached"- путь к прикленному кабелю;
"attackby(var/obj/item/I, var/mob/user)"- Похоже, это список тех, кто может использовать это;
Наш любимый if. Напоминаю, if- проверяет верность утверждения в скобках. Если оно верно, исполнение кода продолжится. Довольно нужный оператор, не правда ли?
"if(istype(I, /obj/item/weapon/screwdriver))"- Если будет использоваться отверка, то исполнение продолжается. Пока просто.
"if(mode == 0)"- Если аппарат выключен
"var/turf/T = loc"- locate- закреплен в турфе.
"if(isturf(T) && !T.intact)"- Если это торф, то подключить. Вроде так, я не совсем понял.
Далее идет потверждение оператора if(?)
"anchored"- подключен;
"mode = 1"- Вид пользования, т.е. закреплен (см. выше)
"user << "You attach the device to the cable."- Сообщение игроку.
"for(var/mob/M in viewers(user))
if(M == user) continue
M << "[user] attaches the power sink to the cable."- при закреплении игроком другим игрокам будет выводится сообщение "[user] attaches the power sink to the cable."
Продолжаем дальше. Самое сложное. Принцип работы.
return
else
user << "Device must be placed over an exposed cable to attach to it."
return
else
if (mode == 2)
processing_objects.Remove(src) // Now the power sink actually stops draining the station's power if you unhook it. --NeoFite
anchored = 0
mode = 0
user << "You detach the device from the cable."
for(var/mob/M in viewers(user))
if(M == user) continue
M << "[user] detaches the power sink from the cable."
ul_SetLuminosity(0)
icon_state = "powersink0"
"return"- Как я понял, возвращение к исполнению основной задачи.
Далее не очень интересно и полезно, нам сейчас основу разобрать надо.
"if (mode == 2)"- Если аппарат подсоединен, то...
"processing_objects.Remove(src)"- Останавливает работу пожирателя.
Далее идет "повторение кода". Нам не интересно. А, еще. Полезная функция:"ul_SetLuminosity(0)"- означает освещение. В данный момент 0- без света.
Идем ниже по коду.
attack_hand(var/mob/user)
switch(mode)
if(0)
..()
if(1)
user << "You activate the device!"
for(var/mob/M in viewers(user))
if(M == user) continue
M << "[user] activates the power sink!"
mode = 2
icon_state = "powersink1"
processing_objects.Add(src)
"attack_hand(var/mob/user)"- Использование рукой игроком.
"switch(mode)
Это только первая часть. Здесь мы узнали о свойствах работы переменных, пожирателя и других ништяков. Перед тем как мы продолжим, я обьясню другие вещи, пока трудно осилить все это, но уже завтра, ок?