ВступлениеОчень интересен вопрос о создании фреймворка для билдера.
То есть, некоторой совокупности частоупотребимых схем, которые используют билдеры, представленных в виде функций, языковых конструкций или операторов - в качестве надстройки к скриптовым движкам.
ПредысторияKadVar писал(а):
Как бы это сказать. С++ конечно хороший язык, но причем тут триггера итп ?
Я видел то, что сделали в сфере, простите но мой вывод: "ниже плинтуса".
Продраться через это практически невозможно.
Проблема не в синтаксисе, хотя у С++ он АБСОЛЮТНО не подходит, проблема в библиотеках, которые вы должны создать для нормальной работы.
Код циркловых мадов, таких как былины и хьервард, а по большей части - и адамант, это native Си-код. Иными словами, куча структурок, процедурное программирование, широкое использование дефайнов.
Насчет сферы, это мад с новой кодовой базой. Там, слава богу, нормальный ООП.
И по сравнению с DG-скрипт, это шаг вперед.
Посудите сами, ведь гораздо проще и понятнее фрагмент:
Код:
foreach (Char ch in Room.Chars) ch.damage(10);
, чем существующая конструкция в DG-скриптах, повторяющая убогость стековой системы циркла:
Код:
set ch %self.people%
while (%ch%)
set next %ch.next_in_room%
wdamage %ch.name% 10
set ch %next%
end
При отсутствии фреймворка, и при наличии ООП в коде мада - я считаю даже вывод С++ - это очень разумный подход. Хотя, конечно, лучше, вывести мад-объекты на более дружественные новичкам скриптовые языки, такие как LUA(
http://ru.wikipedia.org/wiki/Lua), python, и т.п.
KadVar писал(а):
Можно открыть все возможности, но как вы будете контролировать то, что понафигачит рядовой билдер ?
Возможностей в любом случае придется открывать немало. Поэтому контроль - это отдельная тема
KadVar писал(а):
Тут вопрос в том, что нужна непротиворечивая надстройка в виде набора необходимых функций. Причем надстройка удобная в работе. Это подразумевает совсем иной уровень, существенно выше того, который обеспечивает к примеру С++. В том числе и уровень контроля над ошибками. Понимаете... средство разработки зон должно быть ориентированно не на программистов вовсе. Это создание именно своего ЯЗЫКА... задача не такая простая, как кажется.
Это очень правильно конечно, но ведь все зоны очень разные (в идеале, конечно). Поэтому де факто мне в голову приходит лишь несколько вещей, которые можно включить в обсуждаемый фреймворк.
ФреймворкХочется немного конкретики и примеров. Каким он может быть, этот фреймворк?
Итак, сначала выясним, что же требуется делать билдеру чаще всего:
- перечислять объекты (чаще всего персонажей, но также и предметы) по определенному фильтру (по комнате, по лидеру, по признаку моб/не моб, по наличию денег, по внумам и т.п. - по сути это может быть произвольный фильтр) и что-нибудь с ними делать
- выдавать квесты пойди-принеси
- выводить сообщения по типу act
В общем, это и есть те вещи, которые фреймворк должен максимально упростить.
ПеречисленияДумаю, оптимально было бы ввести некую абстрактную конструкцию, например так:
Код:
foreach переменная_объекта in класс_объекта where фильтр
** действия над переменной_объекта
next
переменная_объекта - название произвольной переменной, которой будет присвоен "текущий" объект, с которым можно будет оперировать
класс_объекта - один из: персонажи, предметы, комнаты.
фильтр - условие, в котором можно использовать поля персонажей/предметов/комнат
Примеры:
Код:
foreach ch in chars where room=self.room and !is_npc and align>0
ch.damage(10);
next
Код:
num_of_coins = 0
foreach obj in objects where owner=actor and vnum=8120
num_of_coins += 2
obj.purge
next
if num_of_coins>0
say Отлично, я вижу ты принес то что я просил. Вот твоя награда!
** сгенерим монеты, на случай если у нас столько нет
self.money += num_of_coins
** отдадим их тому кто сделал квест
give actor num_of_coins монет
end
Оба примера предполагаются быть моб-триггерами (self - это моб).
Язык абстрактный, с закосом под адамантовский dg_script.
Первый пример дамажит всех светлых плееров в комнате с текущим мобом.
Второй пример ищет в инвентаре у игрока все предметы с определенным внумом, уничтожает эти предметы и выдает за них по 2 монеты.
Квесты принеси-подайЭто очень частые квесты, и я думаю очень было бы классно, если бы внутри триггеров они были МАКСИМАЛЬНО простыми.
Например, рассмотрим фрагмент:
Код:
register_quest
init
cur_time = get_time()
end
greet
say Привет! Я потерял свою любимую запонку. Если найдешь ее - награжу!
get_mob(1023).attach_death_obj(1020, 100%)
end
award
say Отлично! А я уже и не надеялся ее найти! Вот твоя награда
load obj 1040
give obj_1040 actor
end
conditions
if was_zone_reset_since(10, cur_time)
reset_quest
end
end
end
Подразумевается, что монстр будет давать этот квест один раз за репоп собственной зоны, запонка будет лоадиться в труп монстра 1023 только после того как квест будет взят, награда если принести запонку - предмет 1040.
Согласен, тут много недоработок, но общая мысль, надеюсь понятна: от билдера требуется лишь придумать сообщения, награду, и откуда попится "заказываемый" предмет.
Очень важно, что квест таким образом весь на виду, а не разбросан по разным триггерам: проще искать ошибки.
СообщенияНу тут главное задокументировать как следует, и отказаться от мадовских $N $n $y $g $u $t ..... Я вот сколько лет уже билдю - до сих пор не запомнил. Тем более, что у разных мадов разные переменные... Так что первейшее дело - это переменные назвать, и конечно связать их с объектами. Пример:
Код:
act
to_vict => "Вы содрогнулись от удара молнии, посланной " ch.tname
to_not_vict => vict.name + "содрогнул" + vict.lingvo_sya + " от удара молнии, посланной " ch.tname
to_char => vict.name + "содрогнул" + vict.lingvo_sya + " от удара молнии, посланной Вами!"
end
Вот примерно так. Дополнения приветствуются.