×
Меню
Индекс

MSFD Скриптовая телепортация

Телепортация в случайные (в оригинале: Teleporting to variable positions in interior) т.е. в различные, а не случайные(С) места интерьера и особенно экстерьера не простое дело, были случаи, когда окружающие ячейки не загружались полностью (то есть без части ландшафта) или когда игра вылетала.
Терзают меня смутные сомнения, что все дело в криво указанных координатах было.
Т.е. если кидать игрока без точных данных, он запросто может оказаться внутри объектов, либо под лендскейпом, либо еще что-то-пошло-не-так(С)
Вот решение предложенное Aftershock_81: (и это хреновое решение)
 
COE 0 0 ;если что, здесь используются консольные а не скриптовые собственно команды. COE собственно. Т.е. да, скрипты свободно принимают консольные команды.
;фз, СОЕ 0 0 это нулевая ячейка игры. Собственно Район Эшленда 0 0, где игрок появляется в стене даэдрической башни. Отчего фихми тут более чем оправдан.
;и вопрос "случайности" тоже открыт, фактически это точные координаты ячейки, но указанные "простым способом" т.е. без точных координат "выхода из Варпа"(С).
 
Player->SetPos x xpos
Player->SetPos x ypos
Player->SetPos x zpos
 
FixMe ;это тоже консольная команда для "вылезания" игрока если он застрял в коллизиях.
 
где FixMe должно загрузить ячейку назначения правильно, чтобы избежать проблем, если SetPos будет недостаточно.
 
Nigedo прислал сообщение о проблемах и их решениях в данном подходе:
"Иногда ячейка назначения не загружается правильно даже с FixMe.
В других случаях игра выдает странные сообщения об ошибках или зависает.
Есть мнение, что во многом проблемы возникали из-за Exterior Cell Buffer == не нуль.
С помощью Grumpy и Mode_Locrian (спасибо, парни) я написал скрипт, который работает надежно, по крайней мере в тех тестах, которые я использовал.
Он работает, передвигая игрока в несколько стадий, что позволяет правильно загрузить ячейку.
Для эстетки FadeOut использовано в начале и FadeIn в конце скрипта.
Есть две стадии. Начальные координаты игрока в экстерьере записываются в три глобальные переменные.
Затем нужно использовать StartScript для запуска скрипта обратно в экстерьерВот что-то я этих перемещений в скрипте не обнаружил (Прим. Gwathlobal).
Я пытался использовать более оптимизированную версию, которая бы перемещала игрока на 131072 ед., чтобы уменьшить количество загрузок.
Тут дело в движке, если игрок в экстерьере то вокруг него загружен 2 ячейки во все стороны. И если пытаться его "двигать" то конечно могут возникать некоторого рода проблемы...
Но этот способ иногда не срабатывал. Когда дистанция от 0,0 до точки назначения была ближе чем 8192 ед., ячейка не всегда загружалась и смысл данного подхода исчезал.
Весь способ довольно громоздкий, но он, похоже, надежен."
 
I only ever managed to get Aftershock's method to work via a local script, when I tried using a global script, everything worked, but I got an “Function greater than index count” error.
A good example of using setpos and fixme can be found in Dongle's Ranger Tent mod, available on Planet Elder Scrolls.
If you use FixMe, you may also want to use SetPos again, as fixMe will move the player. It depends on how accurately you want to place the player.
 
 
Скрипт из МСФД 8.1
Скрипт из МСФД 9.0
Begin script_placePC
 
;Global Long Start_PCX
;Global Long Start_PCY
;Global Long Start_PCZ
Float xpos
Float ypos
Float zpos
Long higher
Long lower
Short step
 
If ( step == 0 )
     Player->COE 0 0
     Set step to 1
     Return
Endif
 
Set xpos to ( Player->GetPos x )
Set ypos to ( Player->GetPos y )
 
If ( step == 1 )
     Set higher to ( Start_PCX + 8192 )
     Set lower to ( Start_PCX - 8192 )
     If ( xpos > higher )    
          Set xpos to ( xpos - 8192 )
          Player->SetPos x xpos
     Elseif ( xpos < lower )
          Set xpos to ( xpos + 8192 )
          Player->SetPos x xpos
     Else
          Set step to 2
     Endif
     Return
Elseif ( step == 2 )
     Set higher to ( Start_PCY + 8192 )
     Set lower to ( Start_PCY - 8192 )
     If ( ypos > higher )    
          Set ypos to ( ypos - 8192 )
          Player->SetPos y ypos
     Elseif ( ypos < lower )
          Set ypos to ( ypos + 8192 )
          Player->SetPos y ypos
     Else
          Set step to 3
     Endif
     Return
Elseif ( step == 3 )
     Set xpos to Start_PCX
     Set ypos to Start_PCY
     Set zpos to Start_PCZ
     Player->SetPos x xpos
     Player->SetPos y ypos
     Player->SetPos z zpos
     Set step to 0
     StopScript script_placePC
Endif
 
End
Begin script_PlacePC
 
;Global Float Start_PCX
;Global Float Start_PCY
;Global Float Start_PCZ
Float xpos
Float ypos
Float zpos
Float timer
Short step
 
If ( OnActivate )
     Set step to 1
Endif
 
If ( step == 1 )
     FadeOut 0.1
     ToggleMenus
     Set step to 2
     Return
Elseif ( step == 2 )
     Set timer to ( timer + GetSecondsPassed )
     If ( timer > 0.2 )
          Set timer to 0
          Set step to 3
     Endif
     Return
Elseif ( step == 3 )
     Set step to 0
     Player->COE 0 0
 
     Set xpos to Start_PCX
     Set ypos to Start_PCY
     Set zpos to Start_PCZ
 
     ToggleMenus
 
MenuTest
     MenuTest
 
     Player->SetPos x xpos
     Player->SetPos y ypos
     Player->SetPos z zpos
 
     FixMe
 
     Player->SetPos x xpos
     Player->SetPos y ypos
     Player->SetPos z zpos
 
     FadeIn 0.1
Endif
 
End
 
Похоже в МСФД 8 вошла не правильная версия скрипта, т.е. автор фактически объяснял версию которую не привел в тексте!
Покрайней мере, в РУ версии такая "пьянка".
 
 
 
Примечание: В паре случаев, мой игрок прибывал в точку назначения и умирал. Хехе… Я могу только предположить, что какое-то существо покусало его по пути.
Так что неплохо было бы проводить телепортацию с ToggleGodMode. Эстетика данного процесса очень улучшается при использовании FadeOut и FadeIn, как я уже говорил.
Также ее можно улучшить с помощью ToggleMenus после начальной строки COE, что прячет все меню, в том числе и меню загрузки.
Потом их можно реактивировать, используя: ToggleMenus, MenuTest, MenuTest.
 


На тему телепортации.
Другой пример, где за основу был взят скрипт ленты Брализара.
Т.е. странно, что мсфд не приводит Ванильный беседкин скрипт, но предлагает извращаться с консольными командами, когда много корректнее указать точные координаты.
НО!
Рандом, ака случайность места телепортации определять через, собственно Рандом (Random).
 
Этот скрипт повешен на некий Амулет и при одевании, предлагает телепортацию. Но! "Амулет не совершенен" и может случайным образом, закинуть не в ту ячейку куда предлагает.
 
А это второй скрипт который стартует из первого скрипта, собственно он и определяет рандомность.
Begin AAAA5_controlC
 
short button
short messageOn
short reset
short OnPcEquip
;************************************************************
if ( MenuMode == 1 ) ;скрипт запускается после выходы из меню!
     Return
endif
 
if ( OnPCEquip == 0 )
     set reset to 0
endif
 
if ( reset == 1 )
     return
endif
 
if ( OnPCEquip == 1 )
     if ( reset == 0 )
     Set OnPCEquip to 0
     MessageBox "Вы желаете снова попасть в Забытый Храм?" "Да." "Нет."
     set messageOn to 1
     endif
endif
 
if ( messageOn == 1)
 
     set button to GetButtonPressed
 
if ( button >= 0 )
     set messageOn to 0
endif
 
if ( button == 0 )
     StartScript "AAAA5_controlZZtime" ;это запуск второго скрипта.
     ;Player->PositionCell -32926.172, 48409.191, 271.703, 270, "(The Forgotten Temple)" ;как видно, скрипт можно "исправить" и он будет работать только на целевую локацию. И да, здесь указаны точные координаты точки выхода
;что гарантирует правильный выход в реальный космос!(С)
     PlaySound, "mysticism hit"
     set reset to 1              
elseif ( button == 1 )
     PlaySound, "Item Armor Light Up" ;любой другой звук по вкусу.
     set reset to 1
     return
     endif
endif
 
End
begin AAAA5_controlZZtime
 
;случайный телепорт амулетом.
;***********************************
short RandomPG ;это "рандом" где устанавливается в некое значение. Здесь 17.
;***********************************
set RandomPG to Random 17 ;можно установить в любое другое и делать (например) сбой телепортации, так чтобы амулет вовсе никуда не переносил.
;но, здесь, телепортация происходит всегда, хотя и не в ту ячейку куда предлагает амулет при использовании.
;***********************************
     if ( RandomPG == 0 )
          Player->PositionCell -32693.000, 48425.000, 271.000, 16200, "(The Forgotten Temple)"
          MessageBox "Вы успешно переместились в забытый храм Древней Славы!"
     elseif ( RandomPG == 1 )
          Player->PositionCell -32693.000, 48425.000, 271.000, 16200, "(The Forgotten Temple)"
          MessageBox "Вы успешно переместились в забытый храм Древней Славы!"
     elseif ( RandomPG == 2 )
          Player->PositionCell -32693.000, 48425.000, 271.000, 16200, "(The Forgotten Temple)"
          MessageBox "Вы успешно переместились в забытый храм Древней Славы!"
     elseif ( RandomPG == 3 )
          Player->PositionCell -32693.000, 48425.000, 271.000, 16200, "(The Forgotten Temple)"
          MessageBox "Вы успешно переместились в забытый храм Древней Славы!"
     elseif ( RandomPG == 4 )
          Player->PositionCell, 3996.000, 3920.000, 14408.000, 180, "Tower of Tel Fyr, Hall of Fyr"
          MessageBox "Кажется, Вас занесло в Тель Фир!"
     elseif ( RandomPG == 5 )
          Player->PositionCell 12, 219, -501, 0 "Vivec, High Fane"
          MessageBox "Похоже вы попали в Вивек!"
     elseif ( RandomPG == 6 )
          Player->PositionCell 302.738, 504.307, -368.000, 180 "Falasmaryon, Propylon Chamber"
          MessageBox "Вас занесло в какой-то Пропильон! Похоже амулет иногда сбоит..."
     elseif ( RandomPG == 7 )
          Player->PositionCell 12189.465, 3446.914, 2244.715, 270 "(Halls of Remembering)"
          MessageBox "Странно... Вроде бы это тот Храм, но одновоременно и другой... Какое загадочное место!"
     elseif ( RandomPG == 8 )
          Player->PositionCell 288.000, 2816.000, -48.000, 260 "Gnisis, Temple"
          MessageBox "Прекрасно! вы в Гнисисе!!! Что за ненадежный амулет!"
     elseif ( RandomPG == 9 )
          Player->PositionCell -32693.000, 48425.000, 271.000, 16200, "(The Forgotten Temple)"
          MessageBox "Вы успешно переместились в забытый храм Древней Славы!"
     elseif ( RandomPG == 10 )
          Player->PositionCell, 2077.101, -785.586, -752, 270, "Druscashti, Upper Level"
          MessageBox "Замечательно! Вас занесло в вампирское Капище!"
     elseif ( RandomPG == 11 )
          Player->PositionCell -32693.000, 48425.000, 271.000, 16200, "(The Forgotten Temple)"
          MessageBox "Вы успешно переместились в забытый храм Древней Славы!"
     elseif ( RandomPG == 12 )
          Player->PositionCell -1020.140, -1274.823, 208.000, 270 "Alas Ancestral Tomb"
          MessageBox "Достойно, вы в Гробнице!"
     elseif ( RandomPG == 13 )
          Player->PositionCell -32693.000, 48425.000, 271.000, 16200, "(The Forgotten Temple)"
          MessageBox "Вы успешно переместились в забытый храм Древней Славы!"
     elseif ( RandomPG == 14 )
          Player->PositionCell -253.348, 4301.19, -688.000, 200, "Ebernanit, Shrine"
          MessageBox "Вас занесло куда-то не туда, опять!"
     elseif ( RandomPG >= 15 )
          Player->PositionCell -2.323, -11.847, 89.543, 200, "Ebonheart, Imperial Chapels"
          MessageBox "Кажется это Эбенгард!"
          return
endif
;*************************************************************
StopScript "AAAA5_controlZZtime"
 
end
 
 
И оригинальный беседкин скрипт Ленты Брализара(С)

Begin mazedbandEnd_Script
 
short button
short messageOn
short reset
short OnPcEquip
 
;if ( MenuMode == 1 ) ;да кольцо активируется сразу под меню.
;     Return
;endif
 
if ( OnPCEquip == 0 )
     set reset to 0
endif
 
if ( reset == 1 )
     return
endif
 
if ( OnPCEquip == 1 )
     if ( reset == 0 )
          Set OnPCEquip to 0
          MessageBox "Использовать Ленту Лабиринта для телепортирования в:" "Вивек" "Морнхолд" "Сота Сил" "Никуда"
          if ( GetJournalIndex TR_SothaSil == 100 ) ;здесь опрос на стадии квеста Трибунала, если да конечно нет(С) Т.е. если квест в такой-то стадии, то телепорт будет в другую ячейку.
               set messageOn to 2
          else
               set messageOn to 1
          endif
     endif
endif
 
if ( messageOn == 1 )
 
     set button to GetButtonPressed
 
     if ( button >= 0 )
          set messageOn to 0
     endif
 
     ;vivec
     if ( button == 0 )
          playsound "conjuration hit"
          Player->PositionCell 12, 219, -501, 0 "Vivec, High Fane"
          set reset to 1         
 
     ;mournhold
     elseif ( button == 1 )
          playsound "conjuration hit"
          Player->PositionCell 0, -478, -645, 0 "Mournhold Temple: High Chapel"
          set reset to 1         
 
     ;sotha sil
     elseif ( button == 2 )
          playsound "conjuration hit"
          Player->PositionCell 3976, 4179, 12310, 0 "Sotha Sil, Dome of Sotha Sil"
          set reset to 1
          return
 
     elseif ( button == 3 )
          set reset to 1
          return
 
     endif
 
endif
 
if ( messageOn == 2 )
 
     set button to GetButtonPressed
 
     if ( button >= 0 )
          set messageOn to 0
     endif
 
     ;vivec
     if ( button == 0 )
          MessageBox "Вы чувствуете, как какая-то сила прерывает действие заклинания Ленты Лабиринта и притягивает вас к Морнхолду."
          playsound "conjuration hit"
          Player->PositionCell 0, -478, -645, 0 "Mournhold Temple: High Chapel"
          set reset to 1         
 
     ;mournhold
     elseif ( button == 1 )
          MessageBox "Вы чувствуете, как какая-то сила прерывает действие заклинания Ленты Лабиринта и притягивает вас к Морнхолду."
          playsound "conjuration hit"
          Player->PositionCell 0, -478, -645, 0 "Mournhold Temple: High Chapel"
          set reset to 1         
 
     ;sotha sil
     elseif ( button == 2 )
          MessageBox "Вы чувствуете, как какая-то сила прерывает действие заклинания Ленты Лабиринта и притягивает вас к Морнхолду."
          playsound "conjuration hit"
          Player->PositionCell 0, -478, -645, 0 "Mournhold Temple: High Chapel"
          set reset to 1
          return
 
     elseif ( button == 3 )
          set reset to 1
          return
 
     endif
 
endif
 
 
End