Forum.iFiction.Ru

iFiction.Ru · ifHub · FAQ · IFWiki · QSP · URQ · INSTEAD · AXMA

форум об interactive fiction, текстовых приключенческих играх и всём таком...

Вы не зашли.

0    0    #1
30.04.2011 23:38

Pirate
Участник (+2)
Зарегистрирован: 30.04.2011
Сообщений: 26

описание комнаты и др вопросы от Pirate

Мануал я почитал кусками, вроде что-то понял. На форум ваш иногда заглядываю. Я так гляжу, нубские вопросы выливаются обычно в тему посвящённую не какому-то конкретному вопросу, а какому-то конкретному нубу. Я тоже такую тему себе хочу:)

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

проблемы две:

Код:

Plateau_3: room
    sdesc = "Плато"   
    ldesc =
    {
        "Плоская вершина круглого каменного образования около тысячи метров в диаметре. Отсюда вы можете
         обозревать поверхность планеты на многие километры во все стороны, но везде всё та же знакомая
         картина. Пыльная равнина, тридцатью метрами ниже, простирается во все стороны. Ваш корабль
         виден прямо на юг отсюда. Край скалы продолжается на восток и на запад.";
        if (boulder.location = Plateau_3)
        {
        " \b Вы заметили здоровенный валун к югу. Он около трёх метров в диаметре и, похоже, расположен на
         самом краешке скалы.";
        }
    }
    
    north  = { "Туда идти незачем."; return nil; }  
    nw     = { "Туда идти незачем."; return nil; }
    ne     = { "Туда идти незачем."; return nil; } 
    west   = Plateau_2
    east   = { "Вы прошли несколько сотен метров вдоль края плато, ничего особенного не обнаружили, и вернулись."; return nil; }
    // s, sw or se - impossible     
    
    // in, out, up or down - impossible
;

Код:

boulder: item
  location= Plateau_3
  desc = 'валун/м'
  noun = 'валун/м'
  adjective=  'большой/м' 'валуна' 'валуна#r'
  ldesc= "Большой валун."
  isHer = true
    
  verDoPush(actor) =
  {
  }    
    
  doPush(actor) =
  {
        "Вы налегли на валун, и толкнули изо всех сил. Камень пришёл в движение. Перевалившись через
         край, он медленно покатился, набирая скорость. Несколькими метрами ниже он задел другой валун,
         который покатился, сбивая всё на своём пути. Цепная реакция продолжалась до тех пор, пока
         значительная часть навеса не рухнула вниз, в пыль у основания скалы. Пыль огромным облаком
         поднялась в вакууме, и начала медленно оседать.";

        self.moveInto(nil);  
        BelowCave.ldesc := 'другое, изменившееся описание';
        BelowCave.north := startroom; 
  }
;

1.
Забираюсь я на Plateau_3, и вижу описание комнаты, описание валуна(которое я предусмотрел в описании комнаты), и фразу: "А видишь здесь валун." И эта фраза- лишняя.

2.
Толкаю оттуда валун, и всё бы хорошо, но когда я иду к BelowCave, оказывается, что ldesc не то, чтобы изменилось, а вместо него выводится пустой текст. Это из-за того, что я поставил одинарные кавычки? С двойными кавычками новое описание BelowCave выводится сразу после сталкивания валуна, что мне совсем не надо.

Пробовал я убрать эту строку из doPush, и сделать два описания ldesc внутри объявления BelowCave:room, через if(boulder.location=Plateau_3){}else{}. Не компилится. Грит, каких-то символов ему не хватает.

Отредактировано Pirate (30.04.2011 23:39)

Неактивен

0    0    #2
30.04.2011 23:43

Pirate
Участник (+2)
Зарегистрирован: 30.04.2011
Сообщений: 26

Re: описание комнаты и др вопросы от Pirate

УПС.. Я нашёл FAQ, там есть ответ. Наверное. Надо попробовать.

Неактивен

0    0    #3
30.04.2011 23:54

Pirate
Участник (+2)
Зарегистрирован: 30.04.2011
Сообщений: 26

Re: описание комнаты и др вопросы от Pirate

FAQ я нашёл вверху этого раздела, ссылка вот: http://ifwiki.ru/RTADS_FAQ никогда туда не заглядывал.

Сделал я изменение описания локации, но "А видишь здесь валун" всё равно выводится.

UPD

Требуется помощь.

Отредактировано Pirate (01.05.2011 00:04)

Неактивен

0    0    #4
01.05.2011 09:09

Pirate
Участник (+2)
Зарегистрирован: 30.04.2011
Сообщений: 26

Re: описание комнаты и др вопросы от Pirate

Проблема решилась изменением класса boulder с item на fixeditem.

Логично- мне его таскать с собой не надо. А если бы было надо, то и удобно было бы видеть, где он находится.

Неактивен

0    0    #5
01.05.2011 19:55

fireton
некто с бородой (+354, -92)
Откуда: Москва
Зарегистрирован: 22.08.2005
Сообщений: 1103
Вебсайт

Тон

Re: описание комнаты и др вопросы от Pirate

Я тоже такую тему себе хочу:)

Ну, видишь, сам себе помог. wink

Неактивен

0    0    #6
02.05.2011 16:54

uux
Участник (+884, -80)
Откуда: Москва
Зарегистрирован: 02.12.2006
Сообщений: 1624

Re: описание комнаты и др вопросы от Pirate

Вообще классно, когда люди в состоянии разобраться сами. Чувствуешь, что несколько лет жизни положены не зря. Pirate, так держать!

Неактивен

0    0    #7
02.05.2011 20:40

Pirate
Участник (+2)
Зарегистрирован: 30.04.2011
Сообщений: 26

Re: описание комнаты и др вопросы от Pirate

Код:

BelowCave.north := startroom;

работает нормально, присвоение выполняется, направление выхода изменяется. А что если я хочу вывести описание того, как герой пробирается через этот выход? В описании комнаты делаю так:

Код:

    south  = gotoRockSlide()

, и описываю:

Код:

gotoRockSlide: function
{
        "Вы начали свой спуск по шаткой насыпи, но внезапно поскользнулись, и покатились вместе с
         камнями вниз. Очень скоро вы оказались внизу, с лёгкими ушибами, но без сколько-нибудь
         серьёзных повреждений. \b \b";
    
    return RockSlide;
}

Это я всё делал. Работает.

А теперь проблема: вместо

Код:

BelowCave.north := startroom;

пишу 

Код:

BelowCave.in := GotoEntryChamber();

. И после сталкивания камня выполняется функция, которая должна выполняться при попытке войти в локацию BelowCave. А должно было только измениться поле north локации BelowCave. Попробовал по разному- не получается.

Отредактировано Pirate (02.05.2011 20:42)

Неактивен

0    0    #8
02.05.2011 23:42

Pirate
Участник (+2)
Зарегистрирован: 30.04.2011
Сообщений: 26

Re: описание комнаты и др вопросы от Pirate

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

Действие сталкивания валуна сделал- работает. Особые описания для других выходов делал- работают. И даже получается нормально делать изменение выхода. А когда я пытаюсь слепить особое описание к изменившемуся выходу, то- не получается. А это должна быть распространённая штука- для нестандартного выхода хочется сделать особое описание, чтобы игрок понимал, как он туда попадает.

Отредактировано Pirate (02.05.2011 23:44)

Неактивен

0    0    #9
03.05.2011 06:30

GrAndrey
папа RTADS и Бяка (+49, -2)
Откуда: Москва
Зарегистрирован: 15.09.2002
Сообщений: 1198
Вебсайт

меньше слов

Re: описание комнаты и др вопросы от Pirate

насколько я помню, нельзя переопределять свойства, представляющие собой функцию с выводом (двойными кавычками). Нужно изменить флаг/свойство, по которому будет произведен условный выбор в нужном свойстве. ldesc ли это, north или что-то еще.
Возможно дебагер не жалуется напрямую, но могут происходить совершенно непонятные вещи

Неактивен

0    0    #10
03.05.2011 08:12

Pirate
Участник (+2)
Зарегистрирован: 30.04.2011
Сообщений: 26

Re: описание комнаты и др вопросы от Pirate

GrAndrey, Проблему с ldescr я решил- сделал как написано в FAQ "Как динамически изменить ldesc (и другие свойства с двойными кавычками)?". Проблема с north в том, что когда я делаю аналогично, то код не компилится. Я добивался, что он скомпилился, но работал не так как надо.

А именно: в описании BelowCave я проверяю, столкнут ли boulder, и выбираю нужный текст ldesc- всё хорошо. Аналогичный код для north не компилится. А если для north после проверки, столкнут ли boulder, я делаю

north := GotoEntryChamber();
in:= GotoEntryChamber(); // то же что и north

то такой код выполняется сразу при входе в BelowCave, не дожидаясь пока я попытаюсь пойти на север, или войти. Даже если в функции GotoEntryChamber совсем нет двойных кавычек. Причём выполняется дважды- по разу для каждого описания. А это не удобно. Но раз уж так есть, можно попробовать делать присвоение только в тот момент когда игрок пытается уйти из локации BelowCave. Для этого надо переопределить действие идти применительно к этой локации. Чтобы проверялось направление и столкнутость валуна. Хорошо бы сделать всё корректно- если RTADS умеет показывать игроку список выходов, то выходы north и in тоже должны отображаться корректно, когда они есть. Я так не смогу.

Нужно изменить флаг/свойство, по которому будет произведен условный выбор в нужном свойстве. ldesc ли это, north или что-то еще.

А можно пример кода?

Отредактировано Pirate (03.05.2011 08:27)

Неактивен

0    0    #11
03.05.2011 09:29

GrAndrey
папа RTADS и Бяка (+49, -2)
Откуда: Москва
Зарегистрирован: 15.09.2002
Сообщений: 1198
Вебсайт

меньше слов

Re: описание комнаты и др вопросы от Pirate

Вот фрагменты кода, которые могут быть интересны

Код:

Так одно направление перемещение приравнивается к другому
up={Me.travelTo(north);}

Также есть функции
enterRoom(actor) и leaveRoom( actor ) 

Так описание меняется флагами:
ldesc = {
     if (gobliny.naMost) "Гоблины спешно переходят мост. "; else ...

Можно также как нибудь так:
в определении объекта oneobj  
ldesc = "<<sldesc>>";
в другом месте 
oneobj.sldesc:='lorem ipsum'; 


Так я делал возможность войти в объект "дыра"
    doEnter(actor) = {actor.location.in; actor.travelTo(actor.location.in);}

Уж и не помню почему так

Неактивен

0    0    #12
03.05.2011 21:32

uux
Участник (+884, -80)
Откуда: Москва
Зарегистрирован: 02.12.2006
Сообщений: 1624

Re: описание комнаты и др вопросы от Pirate

Pirate написал:

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

Действие сталкивания валуна сделал- работает. Особые описания для других выходов делал- работают. И даже получается нормально делать изменение выхода. А когда я пытаюсь слепить особое описание к изменившемуся выходу, то- не получается. А это должна быть распространённая штука- для нестандартного выхода хочется сделать особое описание, чтобы игрок понимал, как он туда попадает.

Вообще дело в следующем.

Когда мы пишем в свойствах комнаты (или -в общм случае - вообще объекта)

Код:

north=GotoEntryChamber()

то это - статическое определение, обрабатываемое на этапе компиляции игры. Результатом обработки будет группа инструкций, обуславливающих выполнение функции GotoEntryChamber при каждом обращении к свойству north объекта, для которого написано это определение.

Когда мы пишем в теле какого-нибудь метода/функции

Код:

north:=GotoEntryChamber();

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

Т. е. если функция GotoEntryChamber определена как

Код:

GotoEntryChamber: function
{"Вы проскальзываете во вновь образовавшийся после обвала проход. ";
return startroom;
}

то будет выведено

Код:

Вы проскальзываете во вновь образовавшийся после обвала проход.

после чего свойству north будет присвоено значение startroom.

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

Теперь о том, как решается поставленная Pirate задача в стандарте.

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

Код:

 
boulder: item
//  Здесь прежний код
 BoulderPushed=nil  // Еще не столкнули валун
 doPush(actor) =
  {    // Здесь всё как было
        BoulderPushed=true
  }
;

BelowCave: room
ldesc={if(not boulder.BoulderPushed)
             {"Прежнее описание";
             }
           else
             {"Новое описание";
             }
          }
north={if(not boulder.BoulderPushed)
             {"Этим путем не пройти.";
             }
           else
             {GoToEntryChamber();             
             }
          }
in={return self.north;
     }

Отмечу, что свойство BoulderPushed создано исключительно для наглядности. Вместо него можно было бы проверять свойство location объекта boulder.

И еще одно замечание: хотя теоретически можно присваивать свойствам-направлениям (north и иже с ними) значения помещений динамически, на практике я с таким не сталкивался. Как правило, оформляют всё так, как у меня в примере - со свойствами-флагами и условными операторами. На мой взгляд, это делает код более наглядным и упрощает его отладку.

Кстати, ldesc обычно также оформляется с флагами. Связано это с тем, что ldesc в 99,99 процентах случаев выводит описание посредством оператора "". Днамически присваивать такой оператор затруднительно: результатом динамической инструкции

Код:

ldesc:="Описание";

будет однократный вывод описания и присваивание свойству ldesc пустого значения. Присваивание ldesc строкового значения (в одинарных кавычках) чревато тем, что при осмотре ldesc не будет выводиться (т. к. строковое значение само по себе не содержит инструкции вывода на экран).

Неактивен

0    0    #13
03.05.2011 22:06

Pirate
Участник (+2)
Зарегистрирован: 30.04.2011
Сообщений: 26

Re: описание комнаты и др вопросы от Pirate

Спасибо. Из того что дал GrAndrey, особенно интересен способ присвоить текстовое значение, без вывода его на экран:

Код:

в определении объекта oneobj  
ldesc = "<<sldesc>>";
в другом месте 
oneobj.sldesc:='lorem ipsum';

ну и остальные приёмы тоже очень интересны.

Текст от uux убедил меня в том, что в поведении TADS нет ничего аномального(не считая двойных кавычек). Сейчас попробую код. Кажется я так уже пробовал.

Неактивен

0    0    #14
03.05.2011 22:25

Pirate
Участник (+2)
Зарегистрирован: 30.04.2011
Сообщений: 26

Re: описание комнаты и др вопросы от Pirate

При попытке идти на север описание изменяется, а переход не происходит. Прикрепил свой код.


Прикрепленные файлы:
step0.t, Размер: 11,607 байт, Скачано: 520

Неактивен

0    0    #15
04.05.2011 06:22

uux
Участник (+884, -80)
Откуда: Москва
Зарегистрирован: 02.12.2006
Сообщений: 1624

Re: описание комнаты и др вопросы от Pirate

Pirate написал:

При попытке идти на север описание изменяется, а переход не происходит. Прикрепил свой код.

ОК, моя ошибка. Правильный код выглядит так:

Код:

north={if(boulder.location = Plateau_3)
             {"Этим путем не пройти.";
             }
           else
             {[b]return[/b] GotoEntryChamber();    
             }
}

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

==============================================================================

И еще, кстати, комментарий к коду ГрАнда:

Так я делал возможность войти в объект "дыра"
    doEnter(actor) = {actor.location.in; actor.travelTo(actor.location.in);}

Уж и не помню почему так

Свойства-направления - особые свойства. Когда они возвращают значение-объект, система "знает", что необходимо автоматически переместить главного персонажа в этот объект. Другие свойства/методы этого характерного признака лишены, поэтому для них надо использовать в явном виде метод перемещения персонажей travelTo. Правда, у ГрАнда оно несколько избыточно, вполне хватило бы и такого:

Код:

    doEnter(actor) = {actor.travelTo(actor.location.in);}

При этом важно следить, чтобы actor.location.in не возвращало бы nil. Так что, наверное, наиболее универсально этот код записывается так:

Код:

    doEnter(actor) = {local DestLoc;
                               DestLoc:=actor.location.in;
                               if(DestLoc<>nil)
                                 {actor.travelTo(DestLoc);
                                 }
                             }

Отредактировано uux (04.05.2011 06:22)

Неактивен

0    0    #16
04.05.2011 10:07

Pirate
Участник (+2)
Зарегистрирован: 30.04.2011
Сообщений: 26

Re: описание комнаты и др вопросы от Pirate

Ответы uux вернули угасший было оптимизм. Оказывается, всё можно сделать и компилятор работает логично.

Код:

north={if(boulder.location = Plateau_3)
             {"Этим путем не пройти.";
             }
           else
             {return GotoEntryChamber();    
             }
}

Заработало.

Неактивен

Powered by PunBB
© copyright 2001–2024 iFiction.Ru