Работаем над скриптом
#1
Нам нужно полностью автоматизировать скрипт язык в ПЗ чтобы можно было сделать наш конструктор уровней с проверкой на целостность данных. Мы должны построить блок схему не на логических срипт блоках, а на объектах, указывая связи зависимостей от событий этих самых объектов. Например, объектом можно считать переменную квест и диалоги. У диалогов могут быть методы, в виде каких-то определенных действий, например: запуск окна диалога, блокировки повторного вызова диалога, выдача квеста, и так далее. Соответственно, раз это объект, то объект должен обладать свойствами. Например, объект Диалог, будет обладать следующими виртуальными свойствами: Уникальный номер, Имя, Принадлежность к Персонажу у которого должна проявляться гиперссылка для возможности запуска диалога, и так далее.. Мы должны самостоятельно внести некоторые ограничения в тепершней гибкости скрипта и добавить свои упрощения, которые в момент компиляции будут вставлять нужные блоки. Например, принять некий стандарт для логических условий. В нынешнем ПЗ-скрипте логическое ИЛИ эмулируется из нескольких И, используя временную глобальную переменную, или даже переменные заданий или диалогов. В таком случае, у нас получится релятивная база данных скрипта ПЗ, где сложные ветвления будут автоматически преобразовываться в вид ПЗ-скрипта. Вот, к примеру, нынешний кусок кода в ПЗ. Здесь «ИЛИ» построено при помощи переменной "ZT7", где эта де переменная является защитой от повторного вызова этого окна. Проблема в том, что это не закон и даже не правило. Так как Имя переменной взято в принципе из головы и в других подобных случаях ту же логику «ИЛИ» Дизайнер может сделать по иному.
Script VTriger#0#219
(
if
(
)
then
(
KillScript( )
Sleep( 22 )
"GSSetVar( 0, ""ZT6"", 1 )"
"SendStringEvent( 0, ""tutorial zt6"" )"
VCheck#0#221( this )
VCheck#0#222( this )
)
)
Script VCheck#0#221
(
if
(
WasLooted( LoneWolf )
"Not( IsEqual( GSGetVar( 0, ""ZT7"" ) , 1 ) )"
)
then
(
KillScript( )
VTriger#0#225( this )
)
)
Script VCheck#0#222
(
if
(
Every( i, Boars, IsDead( i ) )
"Not( IsEqual( GSGetVar( 0, ""ZT7"" ) , 1 ) )"
)
then
(
KillScript( )
VTriger#0#225( this )
)
)
Script VTriger#0#225
(
if
(
)
then
(
KillScript( )
"GSSetVar( 0, ""ZT7"", 1 )"
"SendStringEvent( 0, ""tutorial zt7"" )"
)
)
Мы можем выработать правило, чтобы подобные логические узлы всегда были в такой же канонической форме. Или сделать как-то иначе, например:
SS_TEXT
Script VTriger#0#219
(
if
(
)
then
(
KillScript( )
Sleep( 22 )
"GSSetVar( 0, ""ZT6"", 1 )"
"SendStringEvent( 0, ""tutorial zt6"" )"
VCheck#0#221( this )
)
)

Script VCheck#0#221
(
if
(
"IsLess( GSGetVar( 0, ""t.gz1g.zt7"" ) , 2 )"

)
then
(
KillScript( )
VCheck#0#222( this )
)
)

Script VCheck#0#222
(
if
(
IsGreater( add(WasLooted( LoneWolf ),Every( i, Boars, IsDead( i ) ))),0 )
)
then
(
KillScript( )
VTriger#0#225( this )
)
)
Script VTriger#0#225
(
if
(
)
then
(
KillScript( )
"GSSetVarMax( 0, ""t.gz1g.zt7"", 2 )"
"SendStringEvent( 0, ""tutorial zt7"" )"
)
)
логическое «ИЛИ» здесь реализовано на:
IsGreater( add(WasLooted( LoneWolf ),Every( i, Boars, IsDead( i ) ))),0 )
Можно сделать цепочку из вложенного «IF ELSE»:
SS_TEXT
VTriger#0#219( this )
)
)
Script VTriger#0#219
(
if
(
)
then
(
KillScript( )
Sleep( 22 )
"GSSetVar( 0, ""ZT6"", 1 )"
"SendStringEvent( 0, ""tutorial zt6"" )"
VCheck#0#221( this )
)
)
Script VCheck#0#221
(
if
(
"IsLess( GSGetVar( 0, ""t.gz1g.zt7"" ) , 2 )"
)
then
(
KillScript( )
VCheck#0#222( this )
)
)
Script VCheck#0#222
(
if
(
WasLooted( LoneWolf )
)
then
(
KillScript( )
VTriger#0#225( this )
")
if
("
Every( i, Boars, IsDead( i ) )
")
then
(
KillScript( )"
VTriger#0#225( this )
")
)"
Script VTriger#0#225
(
if
(
)
then
(
KillScript( )
"GSSetVarMax( 0, ""t.gz1g.zt7"", 2 )"
"SendStringEvent( 0, ""tutorial zt7"" )"
)
)
Ответ
#2
сложный вопрос - надо думать много
нужно напридумывать эти упрощения на все случаи жизни -
но видно это стоит того
такое обсуждение вообщем то можно в открытой части написать-
правда флейм по этому вопросу вряд ли будет большой
Ответ
#3
В чем собственно проблема и для чего нужно типизировать вообще скрипт.
Скрипт нужно типизировать для того, чтобы можно было точно отследить цепочку зависимостей процедур, и избежать повторений и взаимоисключений в коде. Корень проблемы в том, что нам нужно не создавать новый, а в начале распарсить старый скрипт и классифицировать имеющиеся блоки логических цепочек процедур скрипта.
В принципе скрипт представляет собой модуль связи между выполнением заданий и выдачей новых заданий, автоматически так и через активацию диалогов. Самих макросов в скрипте мало, в основном это макросы не зависимые от игрового процесса. Такие как тренировки лучника, или более сложная процедура, как пинание пять раз Пятачка.
Дело не в сложности, а в том, чтобы эту работу грамотно разбить на части.
Ответ
#4
ага - нужен анализ всех скриптов
я пытался кое-чего - что-то ложится хорошо
в логику а что-то не совсем и требуется какбы ручная доводка
Ответ
#5
Все правильно. Дело в том, что код процедур скрипта Нивала оптимизирован вручную Дизайнерами. А нам нужно сделать что-то подобное уличным знакам, где буду заранее продуманы все нужные комбинации. Задача далеко не тривиальная. По сути дела нам нужно написать свои правила, или позаимствовать логику из визуальных языков, например, то, что у нас будет выглядеть ((False OR True) AND (False OR True)), в Нивальский код придется положить десяток строк из комбинаций:
If
(
)
then
(
)
Задача закодить все это, есть как раз тривиальной задачей.
Вобщем нужно разбить работу и сделать наш формат разобранных процедур скрипта, тогда мы сможем сложить все, что у нас есть. Разбирать, конечно, нужно скрипт для Конструктора уровней. Хотя можно и сам скрипт…
Ответ
#6
Сбойнуло что-то, два одинкаковых текста....
Ответ
#7
Я проверил только что структуру сложной комбинации вложений “if elseIF else”, в принципе, движок к счастью может работать на сложных вложениях. Для такого рода кейсов (свичей), нужно продумать оптимизацию. Например сделать в блоке такого кейса ловушку в самом начале из логическогой последовательности (Выход) AND (Условие1 OR Условие2 OR….). «Выход» -это переменная типа BOOL, ловушка для отмены повторной инициализации единожды выполняемого скрипта. Ну, чтобы кости «Зеленого Дракона» и «Опыт» не сыпался при каждом входе на зоны. В этом случае каждый блок скрипта будет усложняться, но зато мы типизируем весь скрипт, так же нужно поднять на верхние уровни все вложенные условия выполнения следующих заданий и подзаданий. Вкладывать в последовательную цепочку другие задания , на часто посещаемых зонах нельзя. Значить, нужно считать вкладывания, на единожды посещаемой зоне как «дурной тон» в кодинге скриптов этого типа. Особенно блещут вложениями скрипты на зоне 1.
Защешкой может служить любое проверяемое условие, например, isDead(Object), (хотя, лучше использовать Not(isAlive(Object)) ). Так вот Защелка будет следующая:
Script VCheck #0#1
(
If
(
Not(isAlive(Object))
)
then
(
KillScript()
VTriger#0#2
)
)
Script VTriger#0#2
(
If
(
isAlive(Object)
)
then
(
KillScript()
<Список команд>
)
)

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

Так же достаточно плохо, когда привязка сделана к статистическому объекту. Например:
IsLess(DistanceUnitUnit(this,DgunDragon),10), лучше все же использовать однотипность и применить, например: IsLess(DistanceUnitPoint(this,185,95),10). Я имею в виду именно в генераторе скрипта. Вообще, лучше, чтобы иметь в последующем гибкость и не волноваться, что перс может как-то обойти встречу с нужным местом, просто указать зону где находится перс, например самое первое задание когда перс выходит из развалин, нужно тловить не то когда он приблизился к статуе, а то, насколько перс удалился. Опять же, Нивал использовал этот метод, для реплики убегающих Any(i,Peasans,IsLess(DistanceUnitUnit(i,DgunDragon),12)). Вообще, метод правильный, так как в этом случае обрабатывается группа. Вообще по умолчанию везде должна была бы использоваться обработка группы, а не одного перса. Вдруг мы решим играть сразу вдвоем? Во всех места где нужно получить лидера группы нужно использовать только один метод, например функцию GetLeader()
….
Ответ
#8
Сан кстати а почему бы IF-ELSE если не эмулировать CASE не написать нам проще?:
я эту фишку давно заметил
Script VCheck #0#1
(
If
(
Not(isAlive(Object))
)
then
(
KillScript()
<Список команд IF>
)
If
(
)
then
(
KillScript()
<Список команд ELSE>
)
)
Ответ
#9
Нам нужно сделать один элементарный логический блок эмулирующий «ИЛИ», с минимальным вариантом ветвлений, чтобы можно было сразу блок идентифицировать, отследить логику в одном блоке ElseIF.
Здесь у тебя только ELSE а блок ElseIF получится черти где, и сверху и снизу, в общем правила получаются универсальными. Мы повторим универсальность, которая и без того есть в скрипте. Нам нужно создать правила для написания конкретных логических блоков, к конкретному логическому элементу, состоящему из одной скрипт-процедуры.
<Список команд IF> В этом месте ты вставляешь оптимизацию, это ты как программист уже пытаешься оптимизировать систему выполнения скрипта, а этим будет заниматься генератор скрипта. Задачу оптимизации мы пока не ставим, это отдельная задача. Во время генерации скрипта, генератор проанализирует скрипт и сгруппирует вызовы процедур, если надо. В общем, ты написал именно так, как у Нивала есть сейчас. Таким элементарным блоком представлена логика IF, ELSE, а нам нужно IF, ELSEIF, ELSEIF, ….. В самом обработчике скрипта зарезервирована возможность обработки условия ELSEIF, просто Нивальский конструктор почему-то был реализован на сложную схему эмулирования IF, ELSEIF и последовательность ELSEIF неиспользуется как логический элемент.
Опять же, мы немного отклоняемся в сторону. Так как первоначально я завел тему об отсутствии логики «ИЛИ» в скрипте, а здесь мы уже говорим сразу о трех логических элементах: защите от повтора выполнения процедуры, IF, ELSEIF и простого блока IF, ELSE.
Хорошо. Я использую это отступление, чтобы показать на этом примере от чего нам нужно отказаться. Так как ты написал, у Нивала получается сразу все, и кейс, и зависимые условия и последовательность, и все, все, все. То есть, глядя на этот кусок кода нельзя сказать с уверенностью, что какая-то другая процедура не вызывает какую-то часть этого виртуального кейса. Например, кто нам мешает вызвать кусок кода из третьей процедуры, т.е. коды, которые будут в списке: <Список команд ELSE>. Так мы получаем неоднозначность, а если в коде неоднозначность, то это не элементарный блок, а составной блок. Получается, что мы не получим «CASE» как логическую единицу, а будем думать, что это кейс хотя на самом деле это будет просто несколько процедур завязанных в цепочку, где любой сторонний скрипт можем втесаться, и даже создать бесконечный цикл в такой последовательности. Поэтому если говорить о IF, ELSEIF, то его нужно делать в одной процедуре скрипта, с признаками, что это скрипт IF, ELSEIF.
Script VCheck #0#1
(
If
(
<Список условий IF>
)
then
(
KillScript()
<Список вызова скрипт триггеров IF>
)
If
(
<Список условий ELSEIF>
)
then
(
KillScript()
<Список вызова скрипт триггеров ELSEIF>
)
If
(
)
then
(
KillScript()
<Список вызова скрипт триггеров ELSE>
)
)

Итог.
Речь не идет об оптимизированном коде, где мы упростим, свяжем и закрутим связи друг на друга и так далее, речь идет о логическом элементе «ИЛИ» в строке условий! При этом нам нужно «перелопатить» скрипт, чтобы идентифицировать логику уже имеющихся процедур и конвертировать оптимизированную логику у нивала в явный логический вид, пусть даже умышленно увеличивая кол-во повторяющихся процедур.
Ответ
#10
Переставил драйвер видеокарты и модема и смог зайти.
Не знаю что уменя с компом - зашел в первую попавшую тему-
то не запускает одну задачу то другую- то rundll32
то ptssoops(модем) то ddraw.dll - ничего не пойму - возможгно
это вирус но ни один чертов антивирус ничего не находит - чуствую
надо все переставлять кроме замены диска.
Сейчас попробую поработать - пишите.
Ответ


Перейти к форуму:


Пользователи, просматривающие эту тему: 5 Гость(ей)