RU

Возврат на предыдущую локацию

Nex Moderator 05.06.2014 15:00 32 comments 25306 views

Запоминаем текущую локацию при переходе, чтобы потом вернуться на неё.

! В начале игры назначаем обработчик перехода на новую локацию.
$ONNEWLOC = 'ONNEWLOC'

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

! В локации, из которой надо вернуться на предыдущую:
ACT 'Вернуться':
    GOTO $prevLoc
END
Edited at 06.07.2014 17:11 (11 years ago)

При перезаходе на локацию этот код будет работать некорректно

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

Пока что не вижу, чем тебя не устроил вариант в первом сообщении темы.

Что тут непонятного?
Локация, одна. В нее вход с тучи разных локаций.
Требуется, к примеру, выводить картинку в зависимости от того откуда пришел.
Используем метод первого поста темы.

if $nextLoc = 'a': $img = 'a.jpg' 
if $nextLoc = 'b': $img = 'b.jpg'

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

if $prevLoc = 'a': $img = 'a.jpg' 
if $prevLoc = 'b': $img = 'b.jpg'

newsash, вмешиваться в работу назначения $prevLoc вручную крайне не желательно, кроме того это требует неочевидных для автора действий. В таком случае лучше использовать мой способ с dynamic $GoToLoc, $NextLoc. По крайней мере в нем $prevLoc ведет себя предсказуемо и так как ожидается исходя из ее названия.

Почему возник этот вопрос. Открыл несколько игр и о… Решил на досуге оптимизировать код одной из них. Автор(ы) наплодили кучу одинаковых локаций, отличающихся одной-двумя строчками кода. Все отличия вызваны только тем, что заход из разных мест. Соответственно локации реагируют по разному. Хотел их объединить в одну, но так, чтобы потом всем было ясно и понятно при взгляде на мой код почему сделано так, а не иначе и без использования комментариев :) И чтобы в дальнейшем авторы могли пользоваться этим методом без моего участия и не плодили бы 100500 клонов. Чистой воды хобби :)

UPD
Естественно, решив что-то изменить в такой локации, авторы вынуждены править все 100500 :) Что неминуемо должно привести и приводит к ошибкам. То там забыл поправить, то тут.

На мой взгляд, для этих целей больше подходят параметры. Они проще, чем вызов дополнительной функции при переходе.

#a
gt 'c', $curloc
#b
gt 'c', $curloc
#c
if $args[0] = 'a': $img = 'a.jpg' 
if $args[0] = 'b': $img = 'b.jpg' 
... 
some code 
... 
act 'bla-bla': gt $curLoc, $args[0]

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

Понял теперь в чём проблема. Значение переменной $nextLoc изменится при перезаходе на локацию.

Можно вычислять актуальное значение $prevloc в коде локации

$prevLoc = IIF ($CURLOC = $nextloc, $prevLoc, $nextLoc)

либо обновлять его, вызвав принудительно ONNEWLOC.

GS 'ONNEWLOC'

Применив любой из этих подходов, в коде локации можно будет использовать актуальное значение $prevLoc.

Да, можно и с аргументами, это даже проще. Но на мой взгляд, что аргументы, что dynamic $GoToLoc - костыли, требующие от автора всегда помнить, что надо передать параметр. Глядя на уровень кода, могу предсказать, что немногие мозги способны будут такое запомнить :(

Куда проще, когда добрая фея специально написанная процедура будет запоминать то что нужно независимо от скила автора.

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

evp:

Глядя на уровень кода, могу предсказать, что немногие мозги способны будут такое запомнить

Добавить специально написанную процедуру - задача примерно той же сложности.

evp:

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

Для этого должна быть специальная переменная $город или $текущий_город. Городить подобный функционал на логике переходов - извращение (на мой взгляд).

Понимаешь, процедуру хотел добавить я, а они потом пусть пользуются. Но, судя по всему, простого способа решить поставленную задачу нет. Моя идея была создать глобальную переменную по типу $curloc, только она была бы ссылкой не на текущую, а на предыдущую локацию.

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

evp,
можно функцию написать с тем же IIF, которая будет возвращать всегда актуальное значение $prevLoc. И в коде локации получать значение из этой функции.

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

evp:

Моя идея была создать глобальную переменную по типу $curloc, только она была бы ссылкой не на текущую, а на предыдущую локацию.

А можешь всё-таки привести нормальный пример, где нужен именно такой функционал? Потому что я, в основном, вижу случаи, когда при gt $curloc уже неважно, откуда пришел игрок.

Если это прям действительно так важно, то FUNC(’prevloc’) в помощь. Не глобальная переменная, конечно, но нормальный вариант для кодеров-склеротиков :).

А вообще в QSP действительно не хватает служебной локации $onbeforenewloc, которая выполняется ДО каждого перехода (ну или до первого перехода в цепочке переходов, это уже обдумать надо, как лучше).

Возникла вот такая проблема:
в локации “А”:

act 'Вперед':
gt 'A'
end

в локации “B”:

gt 'C'

act 'Назад':
gt 'A'
end

В локации “C”

[операторы]
GOTO $prevLoc

После этого возвращает не в локацию ‘B’, а в локацию “A”. Как исправить? Делал всё как в шапке.

darkangel223,
в начале локации “B” напиши

GS 'ONNEWLOC'

Nex:

в начале локации “B” напиши

Написал в “В” не помогло, но вот если поставить это в “C” то всё работает, спасибо.

darkangel223,
Пожалуйста. Если не сработало в “В”, значит, ты сюда скинул не такой код, как у тебя в игре.

Возникла такая проблема:
- есть лока “рюкзак”, доступная из любой локи, вывожу ссылку на рюкзак через $onnewloc
- в рюкзаке несколько отсеков в т.ч. вложенных
- при возврате на пред. локу через

IF $CURLOC <> $nextLoc: 
    $prevLoc = $nextLoc 
    $nextLoc = $CURLOC 
END

может возникнуть замкнутый круг, о чем писал evp в начале темы

Не могу придумать как сохранить название локи с которой игрок залез в рюкзак, и выходить на нее через $prevloc из главного меню рюкзака (ну или что-то подобное). Навигацию внутри рюкзака я хард кодом распишу.

Log in or Register to post comments.