Перейти к содержанию

Помогите разобраться со скриптом, изымающим/респавнящим книги


Рекомендуемые сообщения

Всем привет,

 

помогите разобраться со скриптом, который проверяет у игрока наличие книги в инвентаре, изымает ее и ставит в определенное место. Скрипт планируется использовать в плагине с автоматической библиотекой: игрок может принести книгу (оригинал) в библиотеку (тут все вроде бы работает, спасибо плагину marcmori), но при попытке вынести ее (т.е. копию с полки) срабатывает скрипт, изымающий книгу и ставящий ее на то место, где она была в первый раз активирована, т.е. на полку. В общем, читать книгу можно, в лут кидать нельзя.

 

Итак, с книги считываются координаты (первый скрипт висит на книге):

begin localScript
 
float xPos
float yPos
float zPos
float angle
 
short OnPCAdd
short doOnce
 
if ( doOnce == 0 )
    set doOnce to 1
    set xPos to ( GetPos X )
    set yPos to ( GetPos Y )
    set zPos to ( GetPos Z )
    set angle to ( GetAngle Z )
    Disable
endif
 
if ( OnPCAdd == 1 )
    set OnPCAdd to 0
    set removerScript.xPos to xPos
    set removerScript.yPos to yPos
    set removerScript.zPos to zPos
    set removerScript.angle to angle
    StartScript removerScript
endif
 
end
 
Затем она изымается и ставится на место:
 
begin removerScript
 
float xPos
float yPos
float zPos
float angle
 
StopScript removerScript
 
if ( player->GetItemCount "copy_bk_QWERTY" )
    player->RemoveItem "copy_bk_QWERTY" 1
    PlaceItem "copy_bk_QWERTY" xPos yPos zPos angle
    return
endif
 
end

 

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

Ссылка на комментарий
Поделиться на другие сайты

Всем привет,

 

помогите разобраться со скриптом, который проверяет у игрока наличие книги в инвентаре, изымает ее и ставит в определенное место. Скрипт планируется использовать в плагине с автоматической библиотекой: игрок может принести книгу (оригинал) в библиотеку (тут все вроде бы работает, спасибо плагину marcmori), но при попытке вынести ее (т.е. копию с полки) срабатывает скрипт, изымающий книгу и ставящий ее на то место, где она была в первый раз активирована, т.е. на полку. В общем, читать книгу можно, в лут кидать нельзя.

 

Итак, с книги считываются координаты (первый скрипт висит на книге):

begin localScript
 
float xPos
float yPos
float zPos
float angle
 
short OnPCAdd
short doOnce
 
if ( doOnce == 0 )
    set doOnce to 1
    set xPos to ( GetPos X )
    set yPos to ( GetPos Y )
    set zPos to ( GetPos Z )
    set angle to ( GetAngle Z )
    Disable
endif
 
if ( OnPCAdd == 1 )
    set OnPCAdd to 0
    set removerScript.xPos to xPos
    set removerScript.yPos to yPos
    set removerScript.zPos to zPos
    set removerScript.angle to angle
    StartScript removerScript
endif
 
end
 
Затем она изымается и ставится на место:
 
begin removerScript
 
float xPos
float yPos
float zPos
float angle
 
StopScript removerScript
 
if ( player->GetItemCount "copy_bk_QWERTY" )
    player->RemoveItem "copy_bk_QWERTY" 1
    PlaceItem "copy_bk_QWERTY" xPos yPos zPos angle
    return
endif
 
end

 

Почему-то не работает. Книга просто берется в инвентарь, ничего не происходит. При входе в ячейку все время считываются координаты.

Подскажите, что не так, пожалуйста.

 

begin localScript
 
float xPos
float yPos
float zPos
float angle
 
if( player->GetItemCount "copy_bk_QWERTY" => 1 )
    set xPos to ( GetPos X )
    set yPos to ( GetPos Y )
    set zPos to ( GetPos Z )
    set angle to ( GetAngle Z )
    set removerScript.xPos to xPos
    set removerScript.yPos to yPos
    set removerScript.zPos to zPos
    set removerScript.angle to angle
    StartScript removerScript
else
return
endif
 
end
 
____________________________________________________________________
 
begin removerScript
 
float xPos
float yPos
float zPos
float angle
 
player->RemoveItem "copy_bk_QWERTY" 1
PlaceItem "copy_bk_QWERTY" xPos yPos zPos angle
 
StopScript removerScript
 
end

 

Попробуйте этот вариант, должно сработать.

Изменено пользователем aL☢
Ссылка на комментарий
Поделиться на другие сайты

aL,

 

нет, не работает. Книга не помещается обратно на место. Просто исчезает из инвентаря.

 

Работает библиотека в одном случае: если на рандомный объект повесить скрипт, декативирующий все книги при первом посещении ячейки. Тогда команду disable из первого скрипта надо убрать.

Но я бы хотел минимизировать количество скриптов и деактивировать книги скриптом, приаттаченном к самой книге (localscript).

Ссылка на комментарий
Поделиться на другие сайты

А если локальные переменные из removerScript вынести в Gameplay->Globals?

Изменено пользователем Муурн Шепард
Ссылка на комментарий
Поделиться на другие сайты

Муурн Шепард,

 

я новичок в скриптах CS, поэтому мне не вполне ясно, что это изменит. Штука в том, что все прекрасно работает, так, как я хочу, при деактивации книги отдельным скриптом. Вот он, аттачим его к какому-нибудь стулу:

 

begin libfirst
short doOnce

 

if ( doOnce == 0 )
set doOnce to 1
"copy_bk_QWERTY"->Disable

 

endif
end

 

Приведенные выше скрипты при этом прекрасно работают (disable убираем из localscript).
Как только я пытаюсь убрать скрипт со стула и прописать disable в localscript, что-то ломается. Книга правильно деактивируется при первом посещении ячейки, появляется по скрипту, проверяющему ее наличие в моем инвентаре (стартует из диалога с библиотекарем), но на место уже не возвращается. Почему - не могу понять. Может, в синтаксисе ошибся.

 

 

begin localScript

 

float xPos
float yPos
float zPos
float angle

 

short OnPCAdd
short doOnce

 

if ( doOnce == 0 )
set doOnce to 1
set xPos to ( GetPos X )
set yPos to ( GetPos Y )
set zPos to ( GetPos Z )
set angle to ( GetAngle Z )
Disable
endif

 

if ( OnPCAdd == 1 )
set OnPCAdd to 0
set removerScript.xPos to xPos
set removerScript.yPos to yPos
set removerScript.zPos to zPos
set removerScript.angle to angle
StartScript removerScript
endif

 

end


Попробовал прописать вместо просто disable вот так:
"copy_bk_QWERTY"->Disable

 

и все заработало. Очень странно.

Изменено пользователем morrow
Ссылка на комментарий
Поделиться на другие сайты

Как только я пытаюсь убрать скрипт со стула и прописать disable в localscript, что-то ломается. Книга правильно деактивируется при первом посещении ячейки, появляется по скрипту, проверяющему ее наличие в моем инвентаре (стартует из диалога с библиотекарем), но на место уже не возвращается.

Потому что PlaceItem не возвращает предмет на место, а создает его копию. Соответственно, с обнуленными переменными. Локальный скрипт отрабатывает опять и делает невидимой "возвращенную" книгу.

 

Ссылка на комментарий
Поделиться на другие сайты

Что же поменялось при ItemID->Disable? По идее, скрипт должен так же отрабатывать и деактивировать книгу.

 

Мне бы очень хотелось избавиться от всех ItemID в этом скрипте. Он будет приаттачен к каждой книге, и подставлять ItemID 500 раз мне бы не хотелось. Пусть будет один на всех, и уже из него запускается removerscript со всеми ItemID.

 

Я попробовал не считывать координаты и использовать SetAtStart, но ничего не поменялось. На всякий случай прописывал Enable с тем же результатом (после SetAtStart):

 

if ( OnPCAdd == 1 )
    set OnPCAdd to 0
    StartScript removerScript
    SetAtStart
endif
Изменено пользователем Veloth
Ссылка на комментарий
Поделиться на другие сайты

Так на стуле уже ничего нет.

 

Со стула скрипт убран, в скрипт на книге прописываем "copy_bk_QWERTY"->disable (вместо просто disable). И внезапно все заработало. Книгу забрать стало невозможно, она удаляется из инвентаря и возникает на положенном ей месте.

Изменено пользователем Veloth
Ссылка на комментарий
Поделиться на другие сайты

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

Ссылка на комментарий
Поделиться на другие сайты

Вы же пишите, что притаскивание книги в библиотеку работает, и она ставится. Почему бы при ее взятии не удалить ее из инвентаря и подменить на дефолтную, после чего снова запустить скрипт размещающий ее?
Ссылка на комментарий
Поделиться на другие сайты

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

Итак, при посещении ячейки стартует скрипт на книге (localscript):

float xPos
float yPos
float zPos
float angle
short OnPCAdd
short doOnce

 

Это мы задаем переменные.

 

if ( doOnce == 0 )
set doOnce to 1

 

Это мы проверяем, в первый ли раз мы в ячейке.

 

if ( doOnce == 0 )
<...>
set xPos to ( GetPos X )
set yPos to ( GetPos Y )
set zPos to ( GetPos Z )
set angle to ( GetAngle Z )
Это мы сохраняем в переменных положение книги при первом посещении ячейки.

 

if ( doOnce == 0 )
<...>
Disable
Это мы деактивируем книгу при первом посещении ячейки.

 

<...>
endif

 

if ( OnPCAdd == 1 )
set OnPCAdd to 0
Это книга каждый фрейм проверяет, не взяли ли ее в инвентарь.

 

Если взяли, то

 

set removerScript.xPos to xPos
set removerScript.yPos to yPos
set removerScript.zPos to zPos
set removerScript.angle to angle
StartScript removerScript

 

Значения переменных переносятся в removerscript, и запускаем этот скрипт.

 

Вот он, задаем переменные для позиционирования книги:
float xPos
float yPos
float zPos
float angle

 

И далее изымаем книгу:
if ( player->GetItemCount "copy_bk_QWERTY" )
player->RemoveItem "copy_bk_QWERTY" 1

 

Ставим на полку, как я понял из вашего объяснения, ее копию с тем же ID:

 

PlaceItem "copy_bk_QWERTY" xPos yPos zPos angle

 

Все.
Как мне кажется, return и if... endif можно убрать, если в библиотеке только одна книга (см. первый ответ на мое сообщение). Они нужны, когда книг много, соответственно, изымается из инвентаря только одна из них.

 

Копия на полке должна, как я понимаю, уже активирована (мы не в первый раз в ячейке).
По факту, почему-то removerscript ломается, чинится только прописанием ID книги в первом скрипте при команде Disable.
Т.е. книга удаляется, но PlaceItem не срабатывает.

 

Так и не понял, почему.

 

 

после чего снова запустить скрипт размещающий ее?


У меня такого скрипта нет, все книги размещены в CS, при первом посещении ячейки они деактивируются.

 

Почему бы при ее взятии не удалить ее из инвентаря и подменить на дефолтную


Ну, я так и делаю, только не подменяю ее в инвентаре на дефолтную. Изменено пользователем morrow
Ссылка на комментарий
Поделиться на другие сайты

Ну вам уже сказали, что прописывание item->disable на самом деле обратится к первой книге. К любой помещенной позже нет.

А мне одна бабка сказала, что placeitem не работает с переменными. Проверьте нулевые координаты ячейки.

И что означает деактивирована? Как книга на полке то появляется?

Ссылка на комментарий
Поделиться на другие сайты

 

Ну вам уже сказали, что прописывание item->disable на самом деле обратится к первой книге. К любой помещенной позже нет.


Ну, на самом деле мне сказали несколько иначе, и я только теперь понял, о чем речь.

 

И что означает деактивирована? Как книга на полке то появляется?


disable/enable:

 

if ( player->GetItemCount "bk_QWERTY" )
if ( "copy_bk_QWERTY"->GetDisabled )
"copy_bk_QWERTY"->Enable
player->PlaySound "Item Book Down"
player->RemoveItem "bk_QWERTY" 1
endif
endif
StopScript LibraryScript

 

 

А мне одна бабка сказала, что placeitem не работает с переменными.


Так работает же. Если ItemID->Disable.

 

В общем, я осознал, что, как сказал Муурн Шепард, PlaceItem создает новую копию с обнуленными переменными, т.е. книга снова станет Disable, а doOnce == 0. Я-то все думал, что это глюк в PlaceItem, а вовсе не в том, что doOnce обнулилась.
Наверное, если не выносить doOnce в глобальные переменные, придется делать еще один счетчик для каждой книги. Если ее уже брали в инвентарь, Disable не выполняется. Пока что придумал вот так, но не работает, как нужно:

 

if ( doOnce == 0 )
set doOnce to 1
set xPos to ( GetPos X )
set yPos to ( GetPos Y )
set zPos to ( GetPos Z )
set angle to ( GetAngle Z )
if ( libcount == 0 )
Disable
endif
endif

Изменено пользователем morrow
Ссылка на комментарий
Поделиться на другие сайты

 

 

 

if ( player->GetItemCount "bk_QWERTY" )

    if ( "copy_bk_QWERTY"->GetDisabled )

        "copy_bk_QWERTY"->Enable

        player->PlaySound "Item Book Down"

        player->RemoveItem "bk_QWERTY" 1

    endif

endif

StopScript LibraryScript

Вот, поэтому я и предложил подменить книгу на дефолтную. Этот скрипт сразу же ее и заберёт.
Ссылка на комментарий
Поделиться на другие сайты

Larkin,

 

на самом деле, я уже решил проблему. По совету Муурн Шепарда сделал глобальную переменную, которая становится == 1, если книгу трогали. (Я сперва по привычке объявил ее в скрипте, поэтому были баги.):

 

if ( doOnce == 0 )
    set doOnce to 1
    set xPos to ( GetPos X )
    set yPos to ( GetPos Y )
    set zPos to ( GetPos Z )
    set angle to ( GetAngle Z )
    Disable
endif
 
if ( libcount == 1 )
    Enable
endif
 
И все заработало.
 
Правда, в библиотеке должно быть очень много книг, и я пока что не понял, как быть. При попытке скоммуниздить книгу она удаляется из инвентаря и возвращается на полку, но при этом все остальные книги в библиотеке тоже становятся Enable :D
Ссылка на комментарий
Поделиться на другие сайты

Ну так конечно, переменная-то одна на все книги. Вариант со стулом мне кажется самым оптимальным.

Ссылка на комментарий
Поделиться на другие сайты

А как вы считаете, хорош ли вариант, при котором книга роняется из ивентаря, а затем move?

Вроде бы, нельзя move предметы из инвентаря, поэтому и роняем. Соответственно, книга не дублируется, переменные не обнуляются.

Ссылка на комментарий
Поделиться на другие сайты

Решил остановиться на варианте со скриптом, приаттаченным к рандомному объекту в ячейке. Не уверен, что введение дополнительной глобальной переменной и ухищрения с move лаконичнее одного дополнительного скрипта.

 

Стал собирать библиотеку, и при тестировании выяснилось, что при попытке воровства книги, стоявшие вертикально, возвращаются на полку уже в лежачем состоянии (команда типа PlaceItem "lib_bk_Airship_Captains_Journal" xPos yPos zPos angle).
Что это и как с этим бороться?..

 


Очевидно, для точного позиционирования объекта требуются углы по всем трем осям: XYZ. Функция PlaceItem поддерживает только Z.

 

В целом,у меня осталось впечатление (поигрался с позиционированием объекта в CS), что и наследование значения переменных для углов Z типа set ScriptName.variable1 to variable2 тоже не работает.

 

Как все же делается такая штука? Мне казалось, что точное позиционирование объекта в различных модах - задача довольно распространенная и стандартная.

Изменено пользователем morrow
Ссылка на комментарий
Поделиться на другие сайты

Копай в направлении что при взятии книги на самом деле активируется и открывается другая книга, а эта дизейблится. Или команда rotate.
Ссылка на комментарий
Поделиться на другие сайты

Копай в направлении что при взятии книги на самом деле активируется и открывается другая книга, а эта дизейблится.

Я уже не пользуюсь PlaceItem, у меня последовательность из нескольких скриптов, в которых последовательно player->drop "ItemID" 1, затем setPos по трем осям, и в последнем скрипте этой цепочки setAngle по трем осям. В самом первом скрипте, как и раньше, снимаются getPos и getAngle. В общем, это все одна и та же книга.

 

 

Или команда rotate

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

Ссылка на комментарий
Поделиться на другие сайты

Так placeitem и не нужен, я бы начал жёстко тестить pcskipequip и onpcequip на книге, сто лет назад я уже тестил, искал способ принудительно закрыть книгу, и выяснил что с книгами эти две команды работают как-то странно. Если отловить взятие книги и вместо этого дизейблить ее, а игроку подсунуть другую, то это решится.

Или можно дропнуть ее из инвентаря и setatstart

Ссылка на комментарий
Поделиться на другие сайты

Что значит не могут быть применены? Команда SetAngle игнорирует переменные? Или у вас не получается передавать их между скриптами?

Ссылка на комментарий
Поделиться на другие сайты

 

Команда SetAngle игнорирует переменные? Или у вас не получается передавать их между скриптами?


Второе.

 


На самом деле, решение уже найдено. Вот это работает в ванильном CS (тестим на одной книге, поэтому удаляющий скрипт объединен с определяющим углы и позицию):

 

Begin localScript1

 

float xPos
float yPos
float zPos
float xAngle
float yAngle
float zAngle
short doOnce
short OnPCAdd
short OnPCDrop

 

if ( doOnce == 0 )
set xPos to GetStartingPos, X
set yPos to GetStartingPos, Y
set zPos to GetStartingPos, Z
set xAngle to GetStartingAngle, X
set yAngle to GetStartingAngle, Y
set zAngle to GetStartingAngle, Z
set doOnce to 1
endif

 

if ( GetPos X != xPos )
if ( GetPos Y != yPos )
if ( GetPos Z != zPos )
SetPos X xPos
SetPos Y yPos
SetPos Z zPos
endif
endif
endif

 

if ( GetAngle X != xAngle )
if ( GetAngle Y != yAngle )
if ( GetAngle Z != zAngle )

 

SetAngle Z zAngle
SetAngle Y yAngle
SetAngle X xAngle
endif
endif
endif

 

if ( OnPCAdd == 1 )
set OnPCAdd to 0
player->drop "lib_bk_poisonsong1" 1
endif

 

End

 

Теперь проблема в другом:
при выставлении книги на полку углы сбиваются. Такое ощущение, что по всем трем осям добавляется по 45 градусов. Как я понял из скриптинга для чайников, это такой баг команды SetAngle.

 

 

Или можно дропнуть ее из инвентаря и setatstart


Нельзя, я уже пробовал.
SetAtStart, кажется, не работает с объектами. Он для разных кнопок (в Призрачных вратах, например). Изменено пользователем morrow
Ссылка на комментарий
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...