RU

Counter и Onnewloc

mkir #1281 02.08.2015 12:25 27 comments 13724 views

Вот уже неоднократно читал везде, что нельзя вообще ничего делать в counter, мол, только в каких-то уникальных и редких случаях. И зная, в общем-то, что собой представляют и counter и onnewloc, до сих пор не совсем понимаю, почему с ними нужно быть осторожнее и что нужно сделать, например, чтобы “перегрузить” counter. В моем текущем проекте (см.Нутбайский наемник) counter перегружен, но все до сих пор вроде бы работает нормально, как и задумывалось, но в данный момент все равно пытаюсь его “разгружать”.

По теме - хотелось бы услышать все за и против.

Edited at 02.08.2015 12:25 (10 years ago)

evp,
не знаю ни одной хорошей текстовой игры, для которой это было бы критично.

Nex:

В ONNEWLOC и COUNTER авторы “запихивают” проверки в основном затем, чтобы избавить себя от вызова локации с проверками. Чтобы писать код, а проверки происходили как бы “сами собой”, без принудительного вызова.

Nex:

Тогда в чём смысл выносить проверки именно в ONNEWLOC? Почему не использовать отдельную локацию для проверок?

Практический смысл вы сами объяснили, а что касается хороших текстовых игр, то отсутствие такой локации не критично (равно, как и для плохих :) текстовых игр), но

evp:

Это сильно упростит жизнь

Практический смысл вы сами объяснили

Неправда.

Выше я подробно расписал, почему подобный подход “а запихаю я все проверки куда-нибудь в COUNTER или ONNEWLOC” не имеет практического смысла, и, более того, вреден, так как приводит к ошибкам.

Проверки дожны быть в специально созданной локации для проверок, и вызываться принудительно. Так и только так. Никаких “обходных путей” не существует, всё это фантазии от непонимания языка.

Введение очередной служебной локации проблему не решит - с ней будет точно такая же история.

Это сильно упростит жизнь

Не вижу, каким образом.

Некоторым не придется в каждой локации в коде “выполнить при посещении” писать в первой строке

gs $ONNEWLOC

:)

В текущей ситуации ONNEWLOC можно использовать практически только для “автоматизации” оформления, критичный код, “автоматически” влияющий на формирование локации и окружающих ее переменных, типа проверок, туда не вставишь.

Хотите пример?

Вот наш с вами код:

! В локации "ONNEWLOC": 
IF $CURLOC <> $nextLoc: 
    $prevLoc = $nextLoc 
    $nextLoc = $CURLOC 
END

Примем, что был осуществлен переход loc1-loc2-loc3 Если автор в loc3 хочет “увидеть” предыдущую локацию, то он, ожидая увидеть loc2 и исходя из здравого смысла напишет:

*nl $prevLoc

Но увидит на экране… loc1!!! Ибо, ONNEWLOC-код еще не отработал и в переменных хранятся значение, актуальные для loc2. С другой стороны, если он дополнит код:

*nl $prevLoc
act 'Back': gt $prevLoc

Он внезапно обнаружит, что, несмотря на то, что экран утверждает $prevLoc = ‘loc1’, переход будет произведен правильно - в loc2. Локация болеет шизофренией, она сама себе противоречит. Причину мы знаем - ONNEWLOC отработал, подставил актуальные значения переменных и на момент, когда игроку дали возможность нажать действие, оно уже будет правильным.

Согласитесь, что это несколько “ломает мозг”, особенно начинающему. Хочется локацию, где можно было бы написать просто:

$prevLoc = $CURLOC

и чтобы код этот срабатывал по факту “покидания” локации, в контексте “старой” локации.

PS Конечно, можно не создавать служебную локацию, а использовать “костыль”. Вместо всех операторов GT использовать

dynamic '$_gt', 'имя_локации_назначения'

где

$_gt = 'gs "ONEXITLOC" & gt $ARGS[0]'

evp,
это пример использования служебной локации по назначению.

А авторы пытаются использовать служебные локации не по назначению, спихивая в них проверки, которые им лень прописывать.

Ещё раз.

Служебные локации должны использоваться по назначению. В чём состоит назначение локаций COUNTER и ONNEWLOC, я написал выше.

Выполнение проверок - это использование не по назначению. И это одинаково справедливо для COUNTER, NEWLOC и гипотетической BEFORENEWLOC.

По назначению - можно и нужно, не по назначению - нельзя, приводит к ошибкам либо не имеет смысла.

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

Вот вам код:

IF наколенники = 0:
    'Стрела попала вам в колено. Вы потеряли много крови...'
    здоровье_игрока = здоровье_игрока - 30
ELSE
    'Стрела ударила по наколеннику и отскочила. Вы порадовались своей предусмотрительности.'
END

IF вода = 1:
    'Вы выпили немного воды из фляги и восстановили силы.'
    здоровье_игрока = здоровье_игрока + 10
END

Если не вызывать “смертельную проверку” сразу после изменения переменной “здоровье_игрока”, то игрок может умереть и возродиться из трупа. И не поможет здесь ни COUNTER, ни ONNEWLOC, ни гипотетический BEFORENEWLOC.

Все эти идеи “а почему бы не обойтись без принудительного вызова проверок”, это просто от непонимания принципов программирования. Не более. “Обойтись” нельзя. И точка.

Это все так, но вы обошли вниманием “шизофрению”. Все-таки, хочется локацию, код которой будет выполняться “до”, а не “после”. Понятно, что этого никто не сделает, как не делают циклы. Так что весь этот разговор впустую. :(

Nex,
А можно спросить , а что будет, если не создавать отдельную локацию для проверки на смерть, а просто сделать кусок кода и вызывать его через dynamic?
Пример:

!где-то в начале прописать:

$check_death = {
  if здоровье < 1:gt 'смерть'
  end
}

!локация, где требуется проверка:
'Вас ударило шайбой по лбу.'
здоровье = здоровье - 10
dynamic $check_death

Можно, результат тот же.

Циклы уже сделаны. Просите Байта, чтобы собрал новый плеер.

Lisichka,
Если не считать того, что такой формы оператора IF не существует (см. грабли), то так можно делать.

Но смысл? Проще создать нормальную локацию и вызвать её через GS, а не извращаться с динамическим кодом.

Nex:

Просите Байта, чтобы собрал новый плеер.

Прошу вас, Nex, как автора плеера Quest Navigator, собрать новую версию :)

evp,
мне не до того сейчас ) слишком большие перемены в жизни…

К тому же, Байт делает коммиты крайне неохотно. Скорее всего, у него на домашнем компе лежит куча незалитых коммитов.

Log in or Register to post comments.