DM Guide 14: различия между версиями

Материал из Chaotic Onyx
Перейти к навигацииПерейти к поиску
(Нет. Сил. Пока.)
Строка 1: Строка 1:
 +
''Это 14-ая глава перевода оригинального руководства по Dream Maker от разработчиков.''
 +
 +
[[All_about_the_code|Остальные главы руководства и статьи о программировании на коде BYOND от любителей на русском.]]
 +
 +
[http://www.byond.com/docs/guide/chap14.html Оригинальная 14-ая глава руководства на английском языке]
 +
{{Заготовка|url="[http://www.byond.com/docs/guide/chap14.html ]"}}
 +
 
Карта использует Декартову систему координат. Необходимы три координаты, что бы определить местоположение объекта на сетке. Координаты, как мы все привыкли, имеют обозначения x, y, z.
 
Карта использует Декартову систему координат. Необходимы три координаты, что бы определить местоположение объекта на сетке. Координаты, как мы все привыкли, имеют обозначения x, y, z.
  
 
Координата "х" определяет местоположение объекта с запад на восток, "по горизонтали". Единица соответствует самой западной точке, а значение world.maxx определяет самую восточную точку. Для игрока х возрастает слева-направо.
 
Координата "х" определяет местоположение объекта с запад на восток, "по горизонтали". Единица соответствует самой западной точке, а значение world.maxx определяет самую восточную точку. Для игрока х возрастает слева-направо.
 
[br]Координата "y" определяет местоположение объекта с юга на запад, "по вертикале". Единица соответствует самой южной точке, а значение world.maxy определяет самую северную точку. Для игрока y возрастает снизу-вверх.
 
[br]Координата "y" определяет местоположение объекта с юга на запад, "по вертикале". Единица соответствует самой южной точке, а значение world.maxy определяет самую северную точку. Для игрока y возрастает снизу-вверх.
[br]Координата "z" идет от 1 до world.maxz, и, как правило, представляет из себя переход от одной высоте к другой. По сути, каждая z-координата - это отдельный уровень. Как правило, для основного уровня используется координата 1. У DM нет встроенного механзима перемещения по Z-уровням, поэтому то, как вы будете использовать Z-координаты, зависит только от вас.  
+
[br]Координата "z" идет от 1 до world.maxz, и, как правило, представляет из себя переход от одной высоте к другой. По сути, каждая z-координата - это отдельный уровень. Как правило, для основного уровня используется координата 1. У DM нет встроенного механизма перемещения по Z-уровням, поэтому то, как вы будете использовать Z-координаты, зависит только от вас.  
  
1. Spatial Instructions
+
==Пространственные инструкции==
  
 
Существует ряд команд для работы с координатами и объектами на карте. Если вы хотите создать что-то, затрагивающее перемещение и пространство, вам они однозначно понадобятся.  
 
Существует ряд команд для работы с координатами и объектами на карте. Если вы хотите создать что-то, затрагивающее перемещение и пространство, вам они однозначно понадобятся.  
  
  
1.1 view list
+
===Список view===
  
View instruction возвращает лист видимых объектов. It is often used without any arguments, but may take a range and center object as parameters.
+
''view '' возвращает список видимых объектов. Часто используется без аргументов, но в качестве параметров можно использовать расстояние и центральный объект.
  
 
view (Range=world.view,Center=usr)
 
view (Range=world.view,Center=usr)
Range is the maximum distance to look.
+
Range – максимальная дальность видимости.
Center is the central object in the view.
+
Center – центральный объект в поле зрения.
Returns a list of visible objects.
+
Возвращает список видимых объектов.
The default view range may be adjusting by setting world.view. The default is 5, which gives you an 11x11 viewport. However, you can increase it up to a maximum of 10, which gives you a 21x21 viewport. (The size of icons may be automatically scaled in order to conveniently fit the map viewport on the player's screen.)
+
 
 +
Дальность видимости по умолчанию может быть настроена при помощи ''world.view''. По умолчанию равна 5, что соответствует видимой области 11 на 11 тайлов. Однако может быть увеличена до 10, что дает видимую область 21 на 21. (Размер иконок может автоматически масштабироваться, для того, чтобы соответствовать видимой области на экране игрока.)
 +
 
 +
Для удобства, аргументы могут быть заданы в любом порядке. Эта возможность чаще всего используется, когда кто-то хочет указать другой центр зрения (center of view), при этом используя диапазон по умолчанию. Например, если вы хотите использовать ''src'', а не ''usr'', в качестве центра зрения, вы можете написать ''view(src)'', а не ''view(5,src)'' или даже ''view(,src)''.
  
As a convenience, the arguments may be specified in any order. This feature is most often used when one wishes to specify a different center of view while still using the default range. For example, if you wanted src rather than usr as the center, you could write view(src) rather than view(5,src) or even view(,src).
+
Дальность видимости равная -1 включает в себя центральный объект и его содержимое. Дальность 0 добавляет к ним тайл (aka turf), на котором находится объект, и прочие объекты, находящиеся на этом тайле. Дальность 1 распространяет зону видимости на область карты, удаленную на один квадрат от центра (по диагонали или в прямом направлении). Дальность равная 2 включает в себя следующую линию тайлов и так далее. По умолчанию дальность равна 5, что включает всю карту 11 на 11, видимую игроком.
  
The range of -1 includes the center object and its contents. A range of 0 adds the center object's turf or room and any other objects inside it. A range of 1 extends to the region on the map one square away from the center (in a diagonal or straight direction). A range of 2 includes the next line of turfs and so on. The default range of 5 includes the entire 11x11 map seen by the player.
+
<div style="width: 10%; float: right; border: 1px solid #AAAAAA; padding: 10px; margin: 10px; background-color: #FFFFDD">
 +
<p style="font-weight: bold; text-align: center">Дальности видимости</p>
 +
<p style="text-align: center">
 +
2 2 2 2 2<br />
 +
2 1 1 1 2<br />
 +
2 1 0 1 2<br />
 +
2 1 1 1 2<br />
 +
2 2 2 2 2</p>
 +
</div>
  
Figure 14.24: Viewing Range
+
Некоторые видимые области могут быть загорожены непрозрачными объектами. Освещенность также играет роль. Если освещение на тайле включено (area.luminosity = 1), то все объекты, находящиеся на нем, будут освещены. Или же отдельные тайлы или объекты на карте могут испускать свет, освещая себя и объекты вокруг. Если ничего не светится, то видны только объекты непосредственно вокруг центра (на расстоянии до 1).
  
2 2 2 2 2
+
Способ влияния непрозрачных объектов на видимость довольно сложен. Грубо говоря, непрозрачные объекты не дают увидеть все, что находится за ними. Для улучшения внешнего вида, любые непрозрачные объекты на краю видимой области также становятся видимы. Этот прием известен как краевая подсветка и часто приводит к значительному улучшению картинки.
2 1 1 1 2
 
2 1 0 1 2
 
2 1 1 1 2
 
2 2 2 2 2
 
Portions of the view may be blocked by opaque objects. Lighting also plays a role. If the background area lighting is on (area.luminosity = 1), all objects inside are illuminated. Otherwise, individual turfs or objects on the map may be luminous, lighting up themselves and the objects around them. If nothing is lit up, only the objects immediately around the center (up to a distance of 1) are visible.
 
  
The way in which opaque objects affect the view is rather complicated. Roughly speaking, opaque objects block the view of anything behind them. To improve the appearance of the view, any opaque objects on the edge of this strictly visible region are also made visible. This is known as boundary highlighting and often yields a much improved effect.
 
  
 +
===Список oview===
  
1.2 oview list
+
''oview '' аналогична ''view '', с той лишь разницей, что не включает в список центральный объект и его содержимое. Другими словами, она исключает объекты из ''view(-1)''. Это чаще всего используется при трансляции сообщение всем в поле зрения, кроме совершившего какое-то действие.
  
The oview instruction is the same as view except it excludes the center object and its contents. In other words, it excludes the objects in view(-1). This is most often useful when broadcasting a message to everyone in view except the perpetrator of some action.
+
===Режим повествования===
  
 +
При описании событий игрокам, можно строго придерживаться третьего лица или использовать смесь второго и третьего лица. Например, когда игрок улыбается, все могут видеть текст "[''usr''] smiles", или же все, кроме игрока, могут это видеть, а игрок вместо этого увидит "You smile".
  
1.2.1 Point of View
+
Преимуществом использования только третьего лица является простота. Подобный прием оставляет ощущение участия в сюжете, в котором персонаж игрока лишь одно из действующих лиц. С другой стороны, повествование от второго лица меньше походит на участие в сюжете и больше напоминает представление, в котором игрок принимает активное участие. Это зависит от вас, на какой эффект Вы рассчитываете.
  
When describing events in the game to players, one may stick strictly to third person or use a mixture of second and third person. For example, when a player smiles, everyone could see the text "[usr] smiles", or everyone but the player could see that and the player could instead see "You smile".
+
Вывод строго от 3-го лица легко генерируется трансляцией всем в ''view()''. Для вывода от второго лица вместо этого используется ''oview()''. Следующие примеры противопоставляют эти два метода.
  
The advantage of a strict third person point of view is simplicity. It tends to have the feel of a story in which the player's mob is one of the characters. A second person point of view, on the other hand, is less like a story and more like a play in which the player is actively taking one of the roles. It's up to you which effect you want.
+
//описание от 3-го лица
 +
mob/verb/smile()
 +
    view() << "[usr] smiles."
  
Strict 3rd person output can simply be generated by broadcasting to all in view(). A second person point of view would instead use oview(). The following examples contrast the two methods.
+
//описание от 2-го лица
 +
mob/verb/smile()
 +
    usr << "You smile."
 +
    oview() << "[usr] smiles."
  
//3rd person description
+
Как правило, действия предполагают наличие трех групп людей: тот, кто совершает действие, тот, над кем совершается действие, и все остальные. При повествовании от второго лица, первые два человека получили бы описания, специально созданные для каждого из них, а все остальные бы получить описание от третьего лица.
mob/verb/smile()
 
  view() << "[usr] smiles."
 
  
//2nd person description
+
Следующий пример демонстрирует, как этого можно добиться.
mob/verb/smile()
 
  usr << "You smile."
 
  oview() << "[usr] smiles."
 
Commonly, actions involve three groups of people: one who performs an action, another who is acted upon, and everyone else. In a second person system, the first two people would get a specially tailored second person description and everyone else would get a third person description.
 
  
The following example demonstrates how this could be achieved.
+
mob/verb/smile(M as mob|null)
 +
    if(!M) //no target mob specified
 +
      usr << "You smile."
 +
      oview() << "[usr] smiles."
 +
    else
 +
      usr << "You smile at [M]."
 +
      M << "[usr] smiles at you."
 +
      oview() - M << "[usr] smiles at [M]."
  
mob/verb/smile(M as mob|null)
+
Напомним, что оператор ''-'' выдает список с исключенным из него заданным элементом. Если бы он не был использован в примере, то персонаж, которому улыбаются, вдобавок получил бы описание от третьего лица.
  if(!M) //no target mob specified
 
      usr << "You smile."
 
      oview() << "[usr] smiles."
 
  else
 
      usr << "You smile at [M]."
 
      M << "[usr] smiles at you."
 
      oview() - M << "[usr] smiles at [M]."
 
Recall that the - operator produces a list with the specified item removed. If that was not used in this example, the mob being smiled at would see the third person description as well.
 
  
  
1.3 range and orange instructions
+
===Инструкции range и orange===
  
The range instruction is exactly like view except it ignores visibility. All objects within the specified range are included in the list whether they are visible or not.
+
''range'' аналогична ''view'', за исключением того, что игнорирует видимость. Все объекты в заданном радиусе будут включены в список независимо от того, видимы они или нет.
  
Similarly, the orange instruction behaves like oview except it also ignores visibility. It returns the same list as range minus the central object and its contents.
+
Таким образом, и ''orange'' ведет себя как ''oview'', за исключением игнорирования видимости. Она возвращает тот же список минус центральный объект и его содержимое.
  
(In case you use it in conversation (I do all the time) it is pronounced `oh-range' and not `orange' like the color. Still, it might be useful to poets in search of a rhyme. Her hair was orange\ And she was in my oh-range...)
+
(На случай использования в разговорной речи, имейте в виду, что произносится `oh-range', а не как цвет или фрукт - `orange'. Тем не менее, это может пригодиться поэтам, подбирающим рифмы. Her hair was orange\ And she was in my oh-range...)
  
 
range (Range=world.view,Center=usr)
 
range (Range=world.view,Center=usr)
 
orange (Range=world.view,Center=usr)
 
orange (Range=world.view,Center=usr)
Range is the maximum distance to look.
+
Range – максимальная дальность видимости.
Center is the central object in the view.
+
Center – центральный объект в поле зрения.
Returns a list of objects within range.
+
Возвращает список объектов в заданном радиусе.
  
1.4 locate instruction
+
===Инструкция locate===
  
The locate instruction is used to get the reference of an object by specifying some unique property of the object. In the case of turfs, the map coordinates may be given. The object type, tag name, and \ref value may also be used to identify the desired object.
+
''locate'' используется для получения ссылки на объект, путем указания некоторых уникальных свойства этого объекта. В случае с тайлами это могут быть координаты. Для идентификации желаемого объекта могут быть использованы ''object type'', ''tag name'' и ''\ref value''.
  
 
locate (x,y,z)
 
locate (x,y,z)
 
locate (Type) in Container
 
locate (Type) in Container
 
locate (Tag) in Container
 
locate (Tag) in Container
x,y,z are turf coordinates.
+
x,y,z – координаты тайла.
Type is the object type.
+
Type – тип объекта.
Tag is a unique text string identifier.
+
Tag – уникальный текстовый идентификатор.
Container is the optional location or list.
+
Container – локация или список (необязательно).
Returns the object or null if none.
+
Возвращает ссылки на объекты или нуль, если их нет.
Using locate() one could place new players on the map at a specific coordinate. The following example moves them to the middle of the map rather than the default position at (1,1,1).
+
 
 +
Используя ''locate()'' можно располагать новых игроков на карте в определенных координатах. В нижеследующем примере они помещаются в центр карты вместо позиции по умолчанию (1,1,1).
 +
 
 +
mob/Login()
 +
    if(!loc) //новый игрок
 +
      loc = locate(world.maxx/2,world.maxy/2,1)
  
mob/Login()
+
Это лишь один из многих случаев, в которых ''locate()'' используется для доступа к объекту в коде, размещенному на карте при помощи редактора карт. Вместо указания координат, как правило, удобнее использовать ''tag variable'' объекта. This can be assigned to a special value и использована, чтобы найти объект во время выполнения программы.
  if(!loc) //new player
 
      loc = locate(world.maxx/2,world.maxy/2,1)
 
This is just one of many cases in which locate() is used to access an object in the code that was created on the map using the map editor. Rather than specify a coordinate, it is usually more convenient to use the tag variable of the object. This can be assigned to a special value and used to find the object at run-time.
 
  
The following example moves new players to a specially tagged location.
+
В следующем примере новые игроки перемещаются в специально помеченные локации.
  
mob/Login()
+
mob/Login()
  if(!loc)
+
    if(!loc)
      loc = locate("start")
+
      loc = locate("start")
A turf would have to be tagged "start" for this to work. Editing the tag variable, as well as other properties of objects, in the map editor will be discussed in section 14.3.
 
  
 +
Необходим тайл, помеченный как "start", чтобы этот пример работал. Редактирование ''tag variable'' и прочих свойств объектов в редакторе карт будет рассмотрено в [[DM_Guide_14 #Программирование, необходимое для создания карт|третьем пункте этой главы]].
  
1.5 block instruction
 
  
The block instruction generates a list of all turfs in a rectangular section on the map.
+
===Инструкция block===
 +
 
 +
''block'' генерирует список всех тайлов в прямоугольной области карты.
  
 
block (SW,NE)
 
block (SW,NE)
SW is the south-west turf.
+
SW – юго-западный тайл области.
NE is the north-east turf.
+
NE – северо-восточный тайл.
Returns a list of turfs in the block.
+
Возвращает список тайлов в области.
The following example uses this to find a particular turf in a region of the map.
 
  
proc/LocateInLevel(Type,zLevel)
+
В следующем примере она используется для нахождения конкретного тайла в области карты.
  var/SW = locate(1,1,zLevel)
 
  var/NE = locate(world.maxx,world.maxy,zLevel)
 
  return locate(Type) in block(SW,NE)
 
This procedure could be used to connect z-levels of the map. If each level had one up-stairs and one down-stairs turf, these could be connected in the following manner.
 
  
turf/downstairs
+
proc/LocateInLevel(Type,zLevel)
  verb/use()
+
    var/SW = locate(1,1,zLevel)
      var/dest = LocateInLevel(/turf/upstairs,z+1)
+
    var/NE = locate(world.maxx,world.maxy,zLevel)
      usr.Move(dest)
+
    return locate(Type) in block(SW,NE)
turf/upstairs
 
  verb/use()
 
      var/dest = LocateInLevel(/turf/downstairs,z-1)
 
      usr.Move(dest)
 
There are many other ways of making turfs which transport the user from one location to another. The destination could be in some fixed position relative to the original turf (for example z+1 or z-1). Another useful method is to mark the destination with a special tag.
 
  
 +
Эта процедура может быть использована для подключения z-уровней карты. Если каждый уровень имеет один тайл начала лестницы и один тайл конца, то они могут быть связаны следующим образом.
  
1.6 get_dist instruction
+
turf/downstairs
 +
    verb/use()
 +
      var/dest = LocateInLevel(/turf/upstairs,z+1)
 +
      usr.Move(dest)
 +
turf/upstairs
 +
    verb/use()
 +
      var/dest = LocateInLevel(/turf/downstairs,z-1)
 +
      usr.Move(dest)
  
The get_dist instruction determines the distance between two locations. The distance is the same as the range parameter to view(). If the objects are in the same place, it is 0. If they are in neighboring positions, it is 1, and so on. (Note that get_dist does not compute the geometric Euclidean distance. It treats diagonal movements as equal to straight ones.)
+
Есть много других способов создания тайлов, перемещающих пользователя из одного места в другое. Пункт назначения может быть в каком-то фиксированном месте относительно исходного тайла (например, z+1 или z-1). Другой полезный способ – пометить место назначения специальным тэгом.
 +
 
 +
 
 +
===Инструкция get_dist===
 +
 
 +
''get_dist'' вычисляет расстояние между двумя точками. Получаемое расстояние соответствует аргументу инструкции ''view()''. Если обе точки находятся в одном месте, то расстояние равно 0. Если они расположены на соседних тайлах, то 1, и так далее. (Обратите внимание, что ''get_dist'' не вычисляет расстояние по теореме Пифагора. При расчете диагональные перемещения считаются равными прямым.)
  
 
get_dist (Loc1,Loc2)
 
get_dist (Loc1,Loc2)
Loc1 is the first location.
+
Loc1 – первая точка.
Loc2 is the second location.
+
Loc2 – вторая точка.
Returns the separating distance.
+
Возвращает расстояние между ними.
This could be used to determine if the target of an action is within range as in the following example.
 
  
mob
+
Она может быть использована для определения, находится ли объект в пределах радиуса действия, как показано в следующем примере.
  var/mob/enemy
 
  proc/Swing()
 
      if(get_dist(src,enemy) > 1) return
 
      //do the damage...
 
In this case, mobs can only strike targets in neighboring positions. The details of the rest of the procedure have been omitted. A typical combat system requires some randomness, which you will see how to do in chapter 16.
 
  
 +
mob
 +
    var/mob/enemy
 +
    proc/Swing()
 +
      if(get_dist(src,enemy) > 1) return
 +
      //далее наносится урон...
  
2. Movement
+
В этом примере, моб может поражать цели только на соседних тайлах. Детали остальной части процедуры были опущены. Типичной боевой системе требуется некоторая случайность, что будет рассмотрено в [[DM_Guide_16|16-ой главе]].
  
There are a number of instructions relating to movement of objects on the map. They are listed in figure 14.25.
 
  
Figure 14.25: Movement Instructions
+
==Перемещение==
  
walk
+
Есть целый ряд инструкций, связанных с перемещением объектов по карте. Они все приведены в сноске справа.
  
walk_towards
+
<div style="width: 10%; float: right; border: 1px solid #AAAAAA; padding: 10px; margin: 10px; background-color: #FFFFDD">
walk_to
+
<p style="font-weight: bold; text-align: center">Инструкции перемещения</p>
walk_away
+
walk<br />
walk_rand
+
walk_towards<br />
step
+
walk_to<br />
 +
walk_away<br />
 +
walk_rand<br />
  
step_towards
 
step_to
 
step_away
 
step_rand
 
get_step
 
  
get_step_towards
+
step<br />
get_step_to
+
step_towards<br />
get_step_away
+
step_to<br />
 +
step_away<br />
 +
step_rand<br />
 +
 
 +
 
 +
get_step<br />
 +
get_step_towards<br />
 +
get_step_to<br />
 +
get_step_away<br />
 
get_step_rand
 
get_step_rand
The three main groups are walk, step, and get_step. These each perform the same computation but differ in how they apply the result. The walk instructions continually move an object, taking multiple steps if necessary. The step instructions do the same except only a single step is taken. The get_step instructions do not move any objects, but return the next location that would be stepped to according to the given walking algorithm.
+
</div>
  
Which group of movement instructions you would want to use depends on how much control you need to take over the process of moving an object. The walk group of instructions completely automates the movement, whereas step allows you to control the timing yourself. For complete control, you can use get_step so that even the decision about whether to move the object or not is left up to you.
+
Есть три основные группы инструкций перемещения '''walk''', '''step''', и '''get_step'''. Все они выполняют одинаковые вычисления, но по-разному используют их результат. Инструкции '''walk''' постоянно перемещают объект, делая несколько шагов при необходимости. Инструкции '''step''' делают то же самое, за исключением того, что совершается только один шаг. Инструкции '''get_step''' не перемещают объект, а возвращают следующий тайл, в который перейдет объект, согласно заданному алгоритму перемещения.
  
The available walking algorithms are described in the following sections. When a ready-made algorithm does not exist to suit your purpose, you may still be able to use one of these in conjunction with your own additions.
+
Какую группу инструкций перемещения вы предпочтете использовать, зависит от того, насколько вы хотите контролировать процесс перемещения объекта. Группа '''walk''' полностью автоматизирует движение, в то время как '''step''' позволяет контролировать timing самостоятельно. Для полного контроля, можно использовать '''get_step''', в этом случае даже решение о том, переместить объект или нет, остается за вами.
  
 +
Доступные алгоритмы перемещения описаны в следующих разделах. Когда готового алгоритма, способного удовлетворить ваши запросы, не существует, вы все равно можете использовать один из них в сочетании с вашими собственными дополнениями.
  
2.1 walk instruction
 
  
The walk, step, and get_step instructions are for movement in a fixed direction.
+
===Инструкции walk===
  
walk (Obj,Dir,Lag=0)
+
''walk'', ''step'', и ''get_step'' – инструкции для движения в заданном направлении.
step (Obj,Dir)
+
instructions are for movement in a fixed direction.
 +
 
 +
walk (Obj,Dir,Lag=0)
 +
step (Obj,Dir)
 
get_step (Obj,Dir)
 
get_step (Obj,Dir)
Obj is the object to move.
+
Obj – передвигаемый объект.
Dir is the direction to move.
+
Dir – направление движения.
Lag is the delay between steps in 10$^th$s of seconds.
+
Lag – задержка между шагами в одну десятую секунды.
The direction argument takes one of the constants NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, or SOUTHWEST. These are the same values used to indicate the direction an object is facing with the dir variable.
+
 
 +
В качестве направления используется одна из констант: NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST или SOUTHWEST. Это те же самые значения, используемые для указания направления взгляда объекта (переменная ''dir'').
  
The step instruction returns 1 on success and 0 on failure and get_step returns the next turf in the given direction. The walk instruction returns immediately and continues to operate in the background since it sleeps before each step.
+
''step'' возвращает 1 в случае успеха и 0 в случае неудачи, а ''get_step'' возвращает следующий тайл в заданном направлении. ''walk'' возвращает значение немедленно и продолжает работать в фоновом режиме, поскольку находится в спящем режиме перед каждым шагом.
  
Only one walking operation may be in effect at one time on a particular object. That means that when walk is invoked, any previous walking operation on that object is aborted. To clear any existing walking operations, one can therefore specify no direction at all: walk(Obj,0).
+
Только одна операция перемещения может выполнятся в единицу времени над конкретным объектом. Это означает, что когда вызывается ''walk'', любая предыдущая операция перемещения этого объекта прерывается. Для отмены любых существующих операций перемещения, можно не задавать направление вовсе ''walk(Obj,0)''.
  
There are a couple of related instructions for dealing with directions. These are described next.
+
Есть несколько инструкций по работе с направлениями. Они описаны в ниже.
  
  
2.1.1 get_dir instruction
+
====Инструкция get_dir====
  
The get_dir instruction computes the direction from one location to another. If the true direction is not exactly equal to one of the eight standard directions (NORTH, SOUTH, and so on), the closest one will be chosen.
+
''get_dir'' вычисляет направление одной локации относительно другой. Если истинное направление не совсем совпадает с одним из восьми стандартных направлений (NORTH, SOUTH и так далее), будет выбрано наиболее близкое.
  
 
get_dir (Loc1,Loc2)
 
get_dir (Loc1,Loc2)
Loc1 is the first location.
+
Loc1 – первая локацияis.
Loc2 is the second location.
+
Loc2 – вторая локация.
Returns the direction from Loc1 to Loc2.
+
Возвращает направление Loc2 относительно Loc1.
  
2.1.2 turn instruction
+
====Инструкция turn====
  
The turn instruction rotates a direction by the specified amount.
+
''turn''
 +
instruction rotates a direction by the specified amount.
  
 
turn (Dir,Angle)
 
turn (Dir,Angle)
Строка 229: Строка 255:
 
The following example defines a guard mob who paces back and forth continuously.
 
The following example defines a guard mob who paces back and forth continuously.
  
mob/guard/New()
+
mob/guard/New()
  ..()
+
    ..()
  spawn for()  //spawn an infinite loop
+
    spawn for()  //spawn an infinite loop
      if(!step(src,dir)) dir = turn(dir,180)
+
      if(!step(src,dir)) dir = turn(dir,180)
      sleep(30) //three seconds
+
      sleep(30) //three seconds
 
By changing the initial direction the guard is facing, he can be made to pace in the desired line. This example shows how you can use the existing walking algorithms for your own purpose--in this case a linear pacing algorithm. Rotating by 90 degrees or 45 degrees instead would produce motion in two dimensions instead of just one. Of course then the guard might wander off and neglect his duties!
 
By changing the initial direction the guard is facing, he can be made to pace in the desired line. This example shows how you can use the existing walking algorithms for your own purpose--in this case a linear pacing algorithm. Rotating by 90 degrees or 45 degrees instead would produce motion in two dimensions instead of just one. Of course then the guard might wander off and neglect his duties!
  
  
2.2 walk_towards
+
===walk_towards===
  
 
The walk_towards, step_towards, and get_step_towards instructions move in the direction of another object. If the target object changes position, the walking algorithm automatically adjusts the direction of motion accordingly.
 
The walk_towards, step_towards, and get_step_towards instructions move in the direction of another object. If the target object changes position, the walking algorithm automatically adjusts the direction of motion accordingly.
Строка 247: Строка 273:
 
Targ is the destination.
 
Targ is the destination.
 
Lag is the delay between steps in 10$^th$s of seconds.
 
Lag is the delay between steps in 10$^th$s of seconds.
 +
 
The return values of these are the same as the fixed-direction movement instructions that have already been described. In fact, all movement instructions behave the same except for the specific stepping algorithm that is employed.
 
The return values of these are the same as the fixed-direction movement instructions that have already been described. In fact, all movement instructions behave the same except for the specific stepping algorithm that is employed.
  
  
2.3 walk_to instruction
+
===walk_to instruction===
  
 
The walk_to, step_to, and get_step_to instructions move to another target object, taking intervening objects into account and attempting to intelligently maneuver around them if possible. If the target is too far away (more than the width of the map view), no action is taken.
 
The walk_to, step_to, and get_step_to instructions move to another target object, taking intervening objects into account and attempting to intelligently maneuver around them if possible. If the target is too far away (more than the width of the map view), no action is taken.
Строка 261: Строка 288:
 
Dist is the maximum desired distance.
 
Dist is the maximum desired distance.
 
Lag is the delay between steps in 10$^th$s of seconds.
 
Lag is the delay between steps in 10$^th$s of seconds.
 +
 
One use for this would be a verb that allows a player to automatically follow another one. That can save a lot of needless key presses, which may otherwise bog down the network. Note that the command takes the player's current distance from the target as the desired range to maintain so that one can avoid crowding in on the leader.
 
One use for this would be a verb that allows a player to automatically follow another one. That can save a lot of needless key presses, which may otherwise bog down the network. Note that the command takes the player's current distance from the target as the desired range to maintain so that one can avoid crowding in on the leader.
  
mob/verb/follow(mob/M)
+
mob/verb/follow(mob/M)
  walk_to(src,M,get_dist(src,M),30)
+
    walk_to(src,M,get_dist(src,M),30)
 +
 
 
As a convenience in situations like this, pressing any direction key will stop the automated walking algorithm. This applies even to the center key, which merely calls walk(src,0) by default, allowing the player to stop in place.
 
As a convenience in situations like this, pressing any direction key will stop the automated walking algorithm. This applies even to the center key, which merely calls walk(src,0) by default, allowing the player to stop in place.
  
  
2.4 walk_away instruction
+
===walk_away instruction===
  
 
The walk_away, step_away, and get_step_away instructions move to another target object, taking intervening objects into account and attempting to intelligently maneuver around them if possible.
 
The walk_away, step_away, and get_step_away instructions move to another target object, taking intervening objects into account and attempting to intelligently maneuver around them if possible.
Строка 281: Строка 310:
 
An example using this algorithm is a command to run away from someone.
 
An example using this algorithm is a command to run away from someone.
  
mob/verb/flee(mob/M)
+
mob/verb/flee(mob/M)
  walk_away(src,M,5,30)
+
    walk_away(src,M,5,30)
  
2.5 walk_rand instruction
+
===walk_rand instruction===
  
 
The walk_rand, step_rand, and get_step_rand instructions generate seemingly random motion. The object being moved appears to wander aimlessly. That is different from wandering mindlessly, which would be the result of random movement. In fact, this algorithm is not very random but instead uses a technique known as edge following to create the effect of purposeful motion.
 
The walk_rand, step_rand, and get_step_rand instructions generate seemingly random motion. The object being moved appears to wander aimlessly. That is different from wandering mindlessly, which would be the result of random movement. In fact, this algorithm is not very random but instead uses a technique known as edge following to create the effect of purposeful motion.
Строка 293: Строка 322:
 
Obj is the object to be moved.
 
Obj is the object to be moved.
 
Lag is the delay between steps in 10$^th$s of seconds.
 
Lag is the delay between steps in 10$^th$s of seconds.
 +
 
The following example uses this walking algorithm to make certain mobs meander through the world.
 
The following example uses this walking algorithm to make certain mobs meander through the world.
  
mob
+
mob
  var/wander
+
    var/wander
  New()
+
    New()
      if(wander) walk_rand(src)
+
      if(wander) walk_rand(src)
      ..()
+
      ..()
 +
 
 
All you have to do to see this in action is define some mobs with the wander variable initialized to 1. The algorithm works best with some edges to follow, so a maze-like map with many tunnels and rooms with walls is ideal.
 
All you have to do to see this in action is define some mobs with the wander variable initialized to 1. The algorithm works best with some edges to follow, so a maze-like map with many tunnels and rooms with walls is ideal.
  
  
3. Programming for Map Design
+
==Программирование, необходимое для создания карт==
  
 
In the simplest scenario, designing the world map is merely a matter of selecting object types which were defined in the code and dropping them onto the map. The individual objects on the map are called instances of the object types and as a group are referred to as the initial map population.
 
In the simplest scenario, designing the world map is merely a matter of selecting object types which were defined in the code and dropping them onto the map. The individual objects on the map are called instances of the object types and as a group are referred to as the initial map population.
Строка 318: Строка 349:
  
  
3.1 Variable Input Parameters
+
===Variable Input Parameters===
  
 
Object variables may be declared in much the same way as verb arguments to provide extra information to the map editor. Both the input type and a list of possible values may be specified. Otherwise a variable simply defaults to accept any type of value.
 
Object variables may be declared in much the same way as verb arguments to provide extra information to the map editor. Both the input type and a list of possible values may be specified. Otherwise a variable simply defaults to accept any type of value.
Строка 326: Строка 357:
 
Type is the input type.
 
Type is the input type.
 
List is the list of possible values.
 
List is the list of possible values.
 +
 
The valid input types include all those which may be used in a verb argument definition. These are described in section 4.5.1. The list of possible values can be a list of constants or a range of integers. The following example demonstrates both possibilities.
 
The valid input types include all those which may be used in a verb argument definition. These are described in section 4.5.1. The list of possible values can be a list of constants or a range of integers. The following example demonstrates both possibilities.
  
mob/var
+
mob/var
 +
    wealth as num
 +
    strength in 1 to 100  //defaults to "as num"
 +
    alignment in list("good","bad","neutral")
 +
    background as text
 +
Figure 14.26: Hands-free programming!
 +
 
 +
Dream Maker's instance editor is a powerful tool, if used appropriately. It can allow you to quickly make unique entities without having to derive new classes for everything. It is also quite simple to use, requiring no other coding knowledge than the ability to fill out forms. Consider the previous code:
 +
 
 +
mob/var
 
   wealth as num
 
   wealth as num
   strength in 1 to 100   //defaults to "as num"
+
   strength in 1 to 100
 
   alignment in list("good","bad","neutral")
 
   alignment in list("good","bad","neutral")
 
   background as text
 
   background as text
Figure 14.26: Hands-free programming!
 
 
Dream Maker's instance editor is a powerful tool, if used appropriately. It can allow you to quickly make unique entities without having to derive new classes for everything. It is also quite simple to use, requiring no other coding knowledge than the ability to fill out forms. Consider the previous code:
 
  
mob/var
 
  wealth as num
 
  strength in 1 to 100
 
  alignment in list("good","bad","neutral")
 
  background as text
 
 
Now suppose you have derived a monster type from this, say, /mob/goblin. Using the instance editor, you can place a bunch of unique goblins on the map without having to modify the DM code one bit:
 
Now suppose you have derived a monster type from this, say, /mob/goblin. Using the instance editor, you can place a bunch of unique goblins on the map without having to modify the DM code one bit:
  

Версия от 17:28, 30 апреля 2015

Это 14-ая глава перевода оригинального руководства по Dream Maker от разработчиков.

Остальные главы руководства и статьи о программировании на коде BYOND от любителей на русском.

Оригинальная 14-ая глава руководства на английском языке

В разработке…


Jobeng.png
Данная статья помечена как неоконченная. Это означает, что статья находится на доработке, поэтому может быть неверна или неактуальна.

Вы можете помочь проекту Onyxyeye@256x256.png Onyx и сообществу Animus-logo.png SS13 в целом — зайдите на наш Bus Mainframes.gif Портал сообщества.
Также вы можете прочитать эту статью на ["[1]" зарубежном вики-проекте].


Карта использует Декартову систему координат. Необходимы три координаты, что бы определить местоположение объекта на сетке. Координаты, как мы все привыкли, имеют обозначения x, y, z.

Координата "х" определяет местоположение объекта с запад на восток, "по горизонтали". Единица соответствует самой западной точке, а значение world.maxx определяет самую восточную точку. Для игрока х возрастает слева-направо. [br]Координата "y" определяет местоположение объекта с юга на запад, "по вертикале". Единица соответствует самой южной точке, а значение world.maxy определяет самую северную точку. Для игрока y возрастает снизу-вверх. [br]Координата "z" идет от 1 до world.maxz, и, как правило, представляет из себя переход от одной высоте к другой. По сути, каждая z-координата - это отдельный уровень. Как правило, для основного уровня используется координата 1. У DM нет встроенного механизма перемещения по Z-уровням, поэтому то, как вы будете использовать Z-координаты, зависит только от вас.

Пространственные инструкции

Существует ряд команд для работы с координатами и объектами на карте. Если вы хотите создать что-то, затрагивающее перемещение и пространство, вам они однозначно понадобятся.


Список view

view возвращает список видимых объектов. Часто используется без аргументов, но в качестве параметров можно использовать расстояние и центральный объект.

view (Range=world.view,Center=usr) Range – максимальная дальность видимости. Center – центральный объект в поле зрения. Возвращает список видимых объектов.

Дальность видимости по умолчанию может быть настроена при помощи world.view. По умолчанию равна 5, что соответствует видимой области 11 на 11 тайлов. Однако может быть увеличена до 10, что дает видимую область 21 на 21. (Размер иконок может автоматически масштабироваться, для того, чтобы соответствовать видимой области на экране игрока.)

Для удобства, аргументы могут быть заданы в любом порядке. Эта возможность чаще всего используется, когда кто-то хочет указать другой центр зрения (center of view), при этом используя диапазон по умолчанию. Например, если вы хотите использовать src, а не usr, в качестве центра зрения, вы можете написать view(src), а не view(5,src) или даже view(,src).

Дальность видимости равная -1 включает в себя центральный объект и его содержимое. Дальность 0 добавляет к ним тайл (aka turf), на котором находится объект, и прочие объекты, находящиеся на этом тайле. Дальность 1 распространяет зону видимости на область карты, удаленную на один квадрат от центра (по диагонали или в прямом направлении). Дальность равная 2 включает в себя следующую линию тайлов и так далее. По умолчанию дальность равна 5, что включает всю карту 11 на 11, видимую игроком.

Дальности видимости

2 2 2 2 2
2 1 1 1 2
2 1 0 1 2
2 1 1 1 2
2 2 2 2 2

Некоторые видимые области могут быть загорожены непрозрачными объектами. Освещенность также играет роль. Если освещение на тайле включено (area.luminosity = 1), то все объекты, находящиеся на нем, будут освещены. Или же отдельные тайлы или объекты на карте могут испускать свет, освещая себя и объекты вокруг. Если ничего не светится, то видны только объекты непосредственно вокруг центра (на расстоянии до 1).

Способ влияния непрозрачных объектов на видимость довольно сложен. Грубо говоря, непрозрачные объекты не дают увидеть все, что находится за ними. Для улучшения внешнего вида, любые непрозрачные объекты на краю видимой области также становятся видимы. Этот прием известен как краевая подсветка и часто приводит к значительному улучшению картинки.


Список oview

oview аналогична view , с той лишь разницей, что не включает в список центральный объект и его содержимое. Другими словами, она исключает объекты из view(-1). Это чаще всего используется при трансляции сообщение всем в поле зрения, кроме совершившего какое-то действие.

Режим повествования

При описании событий игрокам, можно строго придерживаться третьего лица или использовать смесь второго и третьего лица. Например, когда игрок улыбается, все могут видеть текст "[usr] smiles", или же все, кроме игрока, могут это видеть, а игрок вместо этого увидит "You smile".

Преимуществом использования только третьего лица является простота. Подобный прием оставляет ощущение участия в сюжете, в котором персонаж игрока лишь одно из действующих лиц. С другой стороны, повествование от второго лица меньше походит на участие в сюжете и больше напоминает представление, в котором игрок принимает активное участие. Это зависит от вас, на какой эффект Вы рассчитываете.

Вывод строго от 3-го лица легко генерируется трансляцией всем в view(). Для вывода от второго лица вместо этого используется oview(). Следующие примеры противопоставляют эти два метода.

//описание от 3-го лица
mob/verb/smile()
   view() << "[usr] smiles."
//описание от 2-го лица
mob/verb/smile()
   usr << "You smile."
   oview() << "[usr] smiles."

Как правило, действия предполагают наличие трех групп людей: тот, кто совершает действие, тот, над кем совершается действие, и все остальные. При повествовании от второго лица, первые два человека получили бы описания, специально созданные для каждого из них, а все остальные бы получить описание от третьего лица.

Следующий пример демонстрирует, как этого можно добиться.

mob/verb/smile(M as mob|null)
   if(!M) //no target mob specified
      usr << "You smile."
      oview() << "[usr] smiles."
   else
      usr << "You smile at [M]."
      M << "[usr] smiles at you."
      oview() - M << "[usr] smiles at [M]."

Напомним, что оператор - выдает список с исключенным из него заданным элементом. Если бы он не был использован в примере, то персонаж, которому улыбаются, вдобавок получил бы описание от третьего лица.


Инструкции range и orange

range аналогична view, за исключением того, что игнорирует видимость. Все объекты в заданном радиусе будут включены в список независимо от того, видимы они или нет.

Таким образом, и orange ведет себя как oview, за исключением игнорирования видимости. Она возвращает тот же список минус центральный объект и его содержимое.

(На случай использования в разговорной речи, имейте в виду, что произносится `oh-range', а не как цвет или фрукт - `orange'. Тем не менее, это может пригодиться поэтам, подбирающим рифмы. Her hair was orange\ And she was in my oh-range...)

range (Range=world.view,Center=usr) orange (Range=world.view,Center=usr) Range – максимальная дальность видимости. Center – центральный объект в поле зрения. Возвращает список объектов в заданном радиусе.

Инструкция locate

locate используется для получения ссылки на объект, путем указания некоторых уникальных свойства этого объекта. В случае с тайлами это могут быть координаты. Для идентификации желаемого объекта могут быть использованы object type, tag name и \ref value.

locate (x,y,z) locate (Type) in Container locate (Tag) in Container x,y,z – координаты тайла. Type – тип объекта. Tag – уникальный текстовый идентификатор. Container – локация или список (необязательно). Возвращает ссылки на объекты или нуль, если их нет.

Используя locate() можно располагать новых игроков на карте в определенных координатах. В нижеследующем примере они помещаются в центр карты вместо позиции по умолчанию (1,1,1).

mob/Login()
   if(!loc) //новый игрок
      loc = locate(world.maxx/2,world.maxy/2,1)

Это лишь один из многих случаев, в которых locate() используется для доступа к объекту в коде, размещенному на карте при помощи редактора карт. Вместо указания координат, как правило, удобнее использовать tag variable объекта. This can be assigned to a special value и использована, чтобы найти объект во время выполнения программы.

В следующем примере новые игроки перемещаются в специально помеченные локации.

mob/Login()
   if(!loc)
      loc = locate("start")

Необходим тайл, помеченный как "start", чтобы этот пример работал. Редактирование tag variable и прочих свойств объектов в редакторе карт будет рассмотрено в третьем пункте этой главы.


Инструкция block

block генерирует список всех тайлов в прямоугольной области карты.

block (SW,NE) SW – юго-западный тайл области. NE – северо-восточный тайл. Возвращает список тайлов в области.

В следующем примере она используется для нахождения конкретного тайла в области карты.

proc/LocateInLevel(Type,zLevel)
   var/SW = locate(1,1,zLevel)
   var/NE = locate(world.maxx,world.maxy,zLevel)
   return locate(Type) in block(SW,NE)

Эта процедура может быть использована для подключения z-уровней карты. Если каждый уровень имеет один тайл начала лестницы и один тайл конца, то они могут быть связаны следующим образом.

turf/downstairs
   verb/use()
      var/dest = LocateInLevel(/turf/upstairs,z+1)
      usr.Move(dest)
turf/upstairs
   verb/use()
      var/dest = LocateInLevel(/turf/downstairs,z-1)
      usr.Move(dest)

Есть много других способов создания тайлов, перемещающих пользователя из одного места в другое. Пункт назначения может быть в каком-то фиксированном месте относительно исходного тайла (например, z+1 или z-1). Другой полезный способ – пометить место назначения специальным тэгом.


Инструкция get_dist

get_dist вычисляет расстояние между двумя точками. Получаемое расстояние соответствует аргументу инструкции view(). Если обе точки находятся в одном месте, то расстояние равно 0. Если они расположены на соседних тайлах, то 1, и так далее. (Обратите внимание, что get_dist не вычисляет расстояние по теореме Пифагора. При расчете диагональные перемещения считаются равными прямым.)

get_dist (Loc1,Loc2) Loc1 – первая точка. Loc2 – вторая точка. Возвращает расстояние между ними.

Она может быть использована для определения, находится ли объект в пределах радиуса действия, как показано в следующем примере.

mob
   var/mob/enemy
   proc/Swing()
      if(get_dist(src,enemy) > 1) return
      //далее наносится урон...

В этом примере, моб может поражать цели только на соседних тайлах. Детали остальной части процедуры были опущены. Типичной боевой системе требуется некоторая случайность, что будет рассмотрено в 16-ой главе.


Перемещение

Есть целый ряд инструкций, связанных с перемещением объектов по карте. Они все приведены в сноске справа.

Инструкции перемещения

walk
walk_towards
walk_to
walk_away
walk_rand


step
step_towards
step_to
step_away
step_rand


get_step
get_step_towards
get_step_to
get_step_away
get_step_rand

Есть три основные группы инструкций перемещения walk, step, и get_step. Все они выполняют одинаковые вычисления, но по-разному используют их результат. Инструкции walk постоянно перемещают объект, делая несколько шагов при необходимости. Инструкции step делают то же самое, за исключением того, что совершается только один шаг. Инструкции get_step не перемещают объект, а возвращают следующий тайл, в который перейдет объект, согласно заданному алгоритму перемещения.

Какую группу инструкций перемещения вы предпочтете использовать, зависит от того, насколько вы хотите контролировать процесс перемещения объекта. Группа walk полностью автоматизирует движение, в то время как step позволяет контролировать timing самостоятельно. Для полного контроля, можно использовать get_step, в этом случае даже решение о том, переместить объект или нет, остается за вами.

Доступные алгоритмы перемещения описаны в следующих разделах. Когда готового алгоритма, способного удовлетворить ваши запросы, не существует, вы все равно можете использовать один из них в сочетании с вашими собственными дополнениями.


Инструкции walk

walk, step, и get_step – инструкции для движения в заданном направлении. instructions are for movement in a fixed direction.

walk (Obj,Dir,Lag=0) step (Obj,Dir) get_step (Obj,Dir) Obj – передвигаемый объект. Dir – направление движения. Lag – задержка между шагами в одну десятую секунды.

В качестве направления используется одна из констант: NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST или SOUTHWEST. Это те же самые значения, используемые для указания направления взгляда объекта (переменная dir).

step возвращает 1 в случае успеха и 0 в случае неудачи, а get_step возвращает следующий тайл в заданном направлении. walk возвращает значение немедленно и продолжает работать в фоновом режиме, поскольку находится в спящем режиме перед каждым шагом.

Только одна операция перемещения может выполнятся в единицу времени над конкретным объектом. Это означает, что когда вызывается walk, любая предыдущая операция перемещения этого объекта прерывается. Для отмены любых существующих операций перемещения, можно не задавать направление вовсе walk(Obj,0).

Есть несколько инструкций по работе с направлениями. Они описаны в ниже.


Инструкция get_dir

get_dir вычисляет направление одной локации относительно другой. Если истинное направление не совсем совпадает с одним из восьми стандартных направлений (NORTH, SOUTH и так далее), будет выбрано наиболее близкое.

get_dir (Loc1,Loc2) Loc1 – первая локацияis. Loc2 – вторая локация. Возвращает направление Loc2 относительно Loc1.

Инструкция turn

turn instruction rotates a direction by the specified amount.

turn (Dir,Angle) Dir is the initial direction. Angle is the angle to rotate. Returns the new direction. The angle is specified in degrees. For example, turn(NORTH,90) yields WEST, a 90 degrees rotation in the counter-clockwise direction. Negative angles may be specified to achieve clockwise rotations as well.

The following example defines a guard mob who paces back and forth continuously.

mob/guard/New()
   ..()
   spawn for()  //spawn an infinite loop
      if(!step(src,dir)) dir = turn(dir,180)
      sleep(30) //three seconds

By changing the initial direction the guard is facing, he can be made to pace in the desired line. This example shows how you can use the existing walking algorithms for your own purpose--in this case a linear pacing algorithm. Rotating by 90 degrees or 45 degrees instead would produce motion in two dimensions instead of just one. Of course then the guard might wander off and neglect his duties!


walk_towards

The walk_towards, step_towards, and get_step_towards instructions move in the direction of another object. If the target object changes position, the walking algorithm automatically adjusts the direction of motion accordingly.

walk_towards (Obj,Targ,Lag=0) step_towards (Obj,Targ) get_step_towards (Obj,Targ) Obj is the object to be moved. Targ is the destination. Lag is the delay between steps in 10$^th$s of seconds.

The return values of these are the same as the fixed-direction movement instructions that have already been described. In fact, all movement instructions behave the same except for the specific stepping algorithm that is employed.


walk_to instruction

The walk_to, step_to, and get_step_to instructions move to another target object, taking intervening objects into account and attempting to intelligently maneuver around them if possible. If the target is too far away (more than the width of the map view), no action is taken.

walk_to (Obj,Targ,Dist=0,Lag=0) step_to (Obj,Targ,Dist=0) get_step_to (Obj,Targ,Dist=0) Obj is the object to be moved. Targ is the destination. Dist is the maximum desired distance. Lag is the delay between steps in 10$^th$s of seconds.

One use for this would be a verb that allows a player to automatically follow another one. That can save a lot of needless key presses, which may otherwise bog down the network. Note that the command takes the player's current distance from the target as the desired range to maintain so that one can avoid crowding in on the leader.

mob/verb/follow(mob/M)
   walk_to(src,M,get_dist(src,M),30)

As a convenience in situations like this, pressing any direction key will stop the automated walking algorithm. This applies even to the center key, which merely calls walk(src,0) by default, allowing the player to stop in place.


walk_away instruction

The walk_away, step_away, and get_step_away instructions move to another target object, taking intervening objects into account and attempting to intelligently maneuver around them if possible.

walk_away (Obj,Targ,Dist=world.view,Lag=0) step_away (Obj,Targ,Dist=world.view) get_step_away (Obj,Targ,Dist=world.view) Obj is the object to be moved. Targ is the destination. Dist is the minimum desired distance. Lag is the delay between steps in 10$^th$s of seconds. An example using this algorithm is a command to run away from someone.

mob/verb/flee(mob/M)
   walk_away(src,M,5,30)

walk_rand instruction

The walk_rand, step_rand, and get_step_rand instructions generate seemingly random motion. The object being moved appears to wander aimlessly. That is different from wandering mindlessly, which would be the result of random movement. In fact, this algorithm is not very random but instead uses a technique known as edge following to create the effect of purposeful motion.

walk_rand (Obj,Lag=0) step_rand (Obj) get_step_rand (Obj) Obj is the object to be moved. Lag is the delay between steps in 10$^th$s of seconds.

The following example uses this walking algorithm to make certain mobs meander through the world.

mob
   var/wander
   New()
      if(wander) walk_rand(src)
      ..()

All you have to do to see this in action is define some mobs with the wander variable initialized to 1. The algorithm works best with some edges to follow, so a maze-like map with many tunnels and rooms with walls is ideal.


Программирование, необходимое для создания карт

In the simplest scenario, designing the world map is merely a matter of selecting object types which were defined in the code and dropping them onto the map. The individual objects on the map are called instances of the object types and as a group are referred to as the initial map population.

Depending on your preference, it is possible to do little or all of the map design from the code. By creating turfs and other objects with new() part or all of the map could be generated at run-time. Since this is a rather cumbersome method, it is usually reserved for cases where the map is laid out according to some algorithm. For example, a maze-like map could be randomly generated so that it is different each time it is played.

Map generating algorithms are an interesting topic, but the techniques involved are fairly abstract and rely very little on the particulars of the DM language. For an example, refer to the DM Code Library. One of the useful items to be found there is the "Amazing Maze Generator," which can make seemingly infinite dungeons and the like.

In most situations, map design is done principally in the map editor. It is even possible to go beyond simply using pre-defined object types. Using the map editor's instance editing feature, you can modify individual objects to suit your own purposes. This allows one to avoid cluttering up the code with object types which are really just minor variations of a more general type but which are required to make instances on the map.

Using the map editor to its fullest potential, one can write code which is fairly general and independent of the map. This is especially convenient when the programmer and map designer are different people. In fact, the code can be written once and used to design many different maps. This process is referred to as writing a world code base which is then used to create an endless variety of world instances. These could be networked together using techniques described in section 12.6.

The map instance editor allows one to modify the object's variables. For example, you can change the name of an object, its icon, its density, and so forth. There is no limitation to built-in variables; those defined in the code may also be modified. In this case you may wish to specify what sort of value may be given to the variable. This prevents mistakes and also helps inform the map designer about a variable without requiring the poor fellow to read the code.


Variable Input Parameters

Object variables may be declared in much the same way as verb arguments to provide extra information to the map editor. Both the input type and a list of possible values may be specified. Otherwise a variable simply defaults to accept any type of value.

var/VarName as Type in List VarName is the variable being defined. Type is the input type. List is the list of possible values.

The valid input types include all those which may be used in a verb argument definition. These are described in section 4.5.1. The list of possible values can be a list of constants or a range of integers. The following example demonstrates both possibilities.

mob/var
   wealth as num
   strength in 1 to 100   //defaults to "as num"
   alignment in list("good","bad","neutral")
   background as text

Figure 14.26: Hands-free programming!

Dream Maker's instance editor is a powerful tool, if used appropriately. It can allow you to quickly make unique entities without having to derive new classes for everything. It is also quite simple to use, requiring no other coding knowledge than the ability to fill out forms. Consider the previous code:

mob/var
  wealth as num
  strength in 1 to 100
  alignment in list("good","bad","neutral")
  background as text

Now suppose you have derived a monster type from this, say, /mob/goblin. Using the instance editor, you can place a bunch of unique goblins on the map without having to modify the DM code one bit:

Select the goblin type in the tree. Click on the Edit button in the adjacent panel. This will bring up a dialog with the properties of the goblin. Modify these properties by changing the values in the form. If you enter invalid values, the editor will correct you. It does this by looking at the specified filters. For instance, the strength property must be a value between 1 and 100. If it is not in this range, it must be reset. In this fashion, you can change names, descriptions, icons, and so on. You can make a horde of goblins, each with unique identifications and traits. One particular useful property is the tag. This is just a text string that can be used to distinguish instances in the locate() instruction. So if you want to make a "chief goblin" without deriving a new type, you might want to set the tag to "chief goblin" and set the other properties accordingly. You can then locate this goblin later on by doing locate("chief goblin"). After you are done editing the goblins, place them on the map by selecting the corresponding instance in the panel (they will be sorted by tag). If you want to re-edit them later, you can use the Look option and proceed from there.