Скрипты - неотъемлемая часть GECK. При написании возникает очень много казусов. Данная тема должна помочь не наступать на "грабли" новичкам и делиться опытом с другими более продвинутых мододелов.
Всем ку! Я все же не забросил идею со взрывчаткой С4 в 3 фолле. Мне удалось придумать как сделать чтобы мина не взрывалась (ну почти, если прямо на нее встать - бахнет) и удалось сдетонировать ее из консоли. А теперь вопрос: есть ли способ каким-то макаром получить скриптом рефы мин, установленных игроком в текущей локации? По принципу поиска что-ли... ну или совсем костыль: как взаимодействовать со всеми рефами типа FF00xxxx? Нужен скриптовый костыль в виде FF* для взаимодействия со всеми динамическими рефами пользователя.
Stea1ch, надо использовать GetFirstRef ... GetNextRef в цикле (без FOSE его не организовать) . Это для поиска мин в округе. Плюс проверка, что это мина а не что-то другое. Через GetObjectType например. Ну и потом действие над найденной миной - например ее взрыв.
Странно, что вопросы по Фоллу 3 тут задаются, когда есть соотв. тема в разделе 3-ки Или тут типа народу больше?
Вроде, экстендер умеет перебирать ссылки определённого типа функциями GetFirstRef/GetNetRef.
Чтобы мина не взрывалась от присутствия игрока, надо сделать её собственностью игроковой фракции: SetOwnership playerFaction. Только надо сначала получить реф-ссылку на неё, а с этим некоторые трудности.
Чтобы мина не взрывалась вообще, надо сделать её вообще не миной. Сделать мину, которая взрывалась бы по таймеру 0, то есть сразу после появления. Или не сразу, а через секунду-другую, когда уже упадёт и уляжется спокойно. Взрывом ей назначить фальшивый взрыв без повреждений, но имеющий Placed Impact Object. Этому взрыву должен быть обязательно назначен ниф, для невидимых взрывов используется что-то типа nullexplosion.nif, точно уже не помню название. Placed Impact Object должен быть, например, активатором и иметь на себе скрипт, в котором уже можно делать что хочешь. Дистанционный подрыв можно сделать так. Пистолет-детонатор имеет взрывающийся прожектиль, который взрывается сразу при выстреле по таймеру 0. Взрыв тоже фальшивый, но Placed impact object другой. На нём скрипт, который даёт понять скрипту на минах-активаторах, что пора взрываться. Как он может дать понять, если он не знает ссылок на мины? Сделать что-то, что будет заметно всем минам-активаторам. Например, установить какую-нибудь внешнюю переменную (квестовую, глобальную) в единицу. Мины-активаторы в гейммоде постоянно проверяет эту переменную, и как только она становится единицей, размещают на месте себя какой-нибудь взрыв (уже настоящий) PlaceAtMe MineFragExplosion 1, например. Потом мины-активаторы дизейблятся и маркфорделетятся. Можно вместо внешней переменной наложить на игрока пустой эффект секундной длительности и проверять IsSpellTarget, можно ещё что-нибудь придумать, смысл, думаю, понятен: если мы не можем что-то приказать непосредственно ссылке, то пусть она сама за нами внимательно следит, и как только мы подадим некий знак, увидит это и сама сделает всё что нужно.
Сложнее со случаем, когда надо чтобы работало и как простая мина, и как дистанционно подрываемая. В принципе, есть вариант сделать без экстендера на тех же Placed Impacr Object'ах, но он громоздкий и глючноватый из-за особенностей размещения прожектилей функцией PlaceAtMe. Так что, возможно, в перебором ссылок экстендером будет проще и лучше. Если у тебя будет ссылка на мину-прожектиль, то можно с ней делать что хочешь сам, не заставляя её следить за тобой. Таким образом мина-прожектиль будет работать штатным образом как простая мина, а дополнительно можно будет подорвать дистанционно. Не знаю, как у тебя получилось это из консоли, мне приходит в голову только подрыв с помощью другого взрыва. То есть сделать маленький взрывчик маленького радиуса и с маленькими повреждениями, чтобы он только разрушил мину-прожектиль и спровоцировал её подрыв. И тут ещё надо будет придумать, как отследить штатное срабатывание мины от приближения врага, чтобы знать, что эта мина уже взорвана, второй раз взрывать не надо. То есть надо будет, наверное, время от времени снова перебирать ссылки экстендером.
Ну так переношу-то я из NV мину. Собственно я думал что родной скрипт просто надо будет слегка допилить. И да, тут люди есть. Живые. К тому же я в этой теме еще до переезда постигал основы скриптов, чтоб не теряться =))
Чтобы мина не взрывалась вообще, надо сделать её вообще не миной.
Я пытался это сделать, но уперся в полное отсутствие Begin OnFire - в 3 гекке его нет, в FOSE подавно, даже CommandExtender не помог - нет там такого... хотя тул прикольный, функция поиска отлично работает из консольки =)) Пробую сделать подмену на OnDrop - будет двойной функционал - просто мина если юзать как оружие и мина с ду если ее просто выкинуть из инвентаря. Выбрасываться будет активатор с менюхой такой же как и у обычной мины.
Думаю, самое интересное начнется, когда нужно будет начисление опыта за подрыв вражины на такой мине оформлять Хотя может и ошибаюсь - давно это было...
Кстати да, опыт. И ещё надо чтобы актёр взаггрился на игрока, а то ведь искусственно размещаемый взрыв считается ничейным.
Так что наносящий повреждения взрыв всё ж таки должен быть не любой, а специально сделанный. Назначаем ему скриптовый эффект с отмеченным No death dispell. В эффекте пишем SendAssaultAlarm, чтобы разозлить актёра и его друзей. Что с опытом. Можно чисто символически вписать RewardXP 1, просто чтобы что-то звякнуло. Можно долго и нудно скриптово выяснять, кого же мы только что прибили, мы ли его прибили, а то, может, он и раньше так лежал, написать формулу вычисления опыта в зависимости от уровня, типа, роста, веса и общей страшности и в конце выдавать точную дозу опыта.
Изменение репутации для пользователя Stea1ch
Stea1chOffline
Сообщение №1751
написано: 24 ноября 2022, 14:12
| Отредактировано: Stea1ch - 24 ноября 2022, 14:14
Вот из-за этого и приходится громоздить эти Placed Impact Object'ы
Ну я лентяй в хорошем смысле этого слова, так что решил пойти другим путем:
Создал пустой квест C4DetonationQUEST с автостартом и прикрутил к нему скрипт с переменной:
scn C4VarInit
int Detonation
Begin GameMode
if Detonation == 1
set Detonation to 0
endif
end
Создал активатор с моделькой мины и прикрутил к нему скрипт:
scn C4ActivatorSCRIPT
short Button
int Detonate
Begin onActivate
ShowMessage C4Message
end
Begin GameMode
set Detonate to C4DetonationQUEST.Detonation
if Detonate == 1
placeatme C4Explosion
disable
markfordelete
set C4DetonationQUEST.Detonation to 0
set Detonate to 0
endif
set Button to GetButtonPressed
if Button == 0
player.additem WeapC4PlasticExplosive 1 0
disable
markfordelete
elseif Button == 1
endif
end
Прикрутил к мине скрипт для подмены оной на активатор при выбрасывании:
scn C4SCRIPT
Begin OnDrop
placeatme C4Activator
disable
markfordelete
end
И наконец создал скриптовый эффект для оружия и прикрутил его к детонатору:
scn DetonatorEffect
begin ScriptEffectStart
set C4DetonationQUEST.Detonation to 1
end
begin ScriptEffectUpdate
set C4DetonationQUEST.Detonation to 1
end
begin ScriptEffectFinish
set C4DetonationQUEST.Detonation to 0
end
И... НИХРЕНА не работает. По логике эффект должен сработать при выстреле... ЧЯДНТ?
Изменение репутации для пользователя JupiterJour
JupiterJourOffline
Сообщение №1752
написано: 24 ноября 2022, 15:02
| Отредактировано: JupiterJour - 24 ноября 2022, 15:14
Нет, оружейный эффект должен сработать на цели при попадании. И то, только если оружие наносит хотя бы единичку повреждения. То есть сейчас детонатор работает так: находим кого-нибудь, стреляем в него - и мины взрываются, если эффект имеет длительность. Если не имеет, то не взрываются, потому что эффект сам же сразу и обнуляет переменную. Всё, что требуется - это в скрипте Placed impact object'а (объектном скрипте) написать:
set C4DetonationQUEST.Detonation to 1
Disable
MarkForDelete
Далее. Вот тут лишнее:
set Detonate to C4DetonationQUEST.Detonation
Можно ж просто проверять саму квестовую переменную, не переписывая её постоянно в другую переменную:
if C4DetonationQUEST.Detonation == 1
Далее. Обнулять квестовую переменную из скрипта мины-активатора не нужно. Если мин больше одной, сработает первая, обнулит переменную - и всё, другие не сработают. Можно обнулить её в самом квесте, но не как сейчас сделано (а вдруг так совпадёт, что квестовый скрипт сработает раньше объектного?), а по таймеру, скажем, через секунду-две. Тогда, думаю, надо сделать так. Квест сделать изначально отключенным. Script processing delay сделать ему побыстрее - 0.1 или 0.05. Включать квест там же, где взводится переменная, в скрипте PIO - дописать туда StartQuest или лучше
if GetQuestRunning C4DetonationQUEST == 0
StartQuest C4DetonationQUEST
endif
Отключать квест и обнулять переменную по таймеру в самом квесте.
По-моему, с пустым "сигнальным" эффектом на игроке возни меньше, чем со всеми этими переменными и таймерами, но тут дело вкуса.
потому что эффект сам же сразу и обнуляет переменную.
Исправил. Убрал из скрипта эффекта все, кроме начала, из квестового скрипта блок Begin (оставил только переменную, которой 0 задается на стадии 0 самого квеста). Обнуляется значение переменной только в случае успешной детонации. Из консоли проверил - взрывается.
Цитата JupiterJour
Если мин больше одной, сработает первая, обнулит переменную
Исправил. Создал задержку перед обнулением на 1 секунду. Взрываются все.
Цитата JupiterJour
Далее. Вот тут лишнее:
Сам допер и убрал =))
Цитата JupiterJour
Всё, что требуется - это в скрипте Placed impact object'а (объектном скрипте) написать:
А вот это пока мне не понятно. Поколдую еще, кажется я на верном пути =))
Скриптовый эффект для оружия, как и любой эффект для оружия накладывается на цель при попадании зачарованным оружием по этой цели. Если так и задумано, что для подрыва мины надо стрельнуть детонатором в случайно пробегающую мимо собаку, то всё нормально, можно ничего не менять. Если же надо, чтобы мина взрывалась при выстреле детонатором хоть в собаку, хоть в небо, хоть куда, то надо сколхозить в трёшке что-то вроде блока OnFire, чтобы скрипт запускался при любом выстреле вне зависимости от попадания в кого-то или во что-то. А единственный способ в трёшке запустить скрипт при выстреле вне зависимости от попадания- это подорвать прожектиль, разместить на его месте PIO и запустить скрипт на этом PIO.
Изменение репутации для пользователя Stea1ch
Stea1chOffline
Сообщение №1755
написано: 25 ноября 2022, 01:25
| Отредактировано: Stea1ch - 25 ноября 2022, 01:53
это подорвать прожектиль, разместить на его месте PIO и запустить скрипт на этом PIO.
Да так и сделал. Избавился от эффекта от слова совсем, создал активатор и привязал его как PIO к взрыву прожектеля, прикрутил к нему скрипт:
scn C4DetonatorImpactOBJ
Begin GameMode
if GetQuestRunning C4DetonationQUEST == 0
StartQuest C4DetonationQUEST
endif
set C4DetonationQUEST.Detonation to 1
Disable
MarkForDelete
end
И... не работает. Из консольки без вопросов взрывается. Прикрутил также проверку на запуск квеста и запуск если не запущен на onEquip детонатора. В квесте одна стадия с result скриптом set C4DetonationQUEST.Detonation to 0; Сам квест без автостарта, проверял, стартует. Сам прожектель детонирует с задержкой 0 и дистанцией 0. Прикручивал эффект - виден при выстреле. Менял дистанцию подрыва на 0.1 и задержку на 0.1 - получил летающий терминал чужих (именно эту модельку я впихнул в активатор, который PIO) без подрыва мины. Такое ощущение что на прикрученный к PIO скрипт движку просто наср@ть - он не выполняется. В общем все чудесатее и чудесатее.
Уря! Заработало! Не тот блок! Поменял GameMode на onload - вуоля! Бабахает. Осталась косметика, где и как обнулять и подобное! Спасибо всем за помощь!
PS для администраторов сайта: ДО СИХ ПОР НЕ РАБОТАЮТ ТЕКСТОВЫЕ ЭФФЕКТЫ. ЗАЧЕРНКУТЫЙ ТЕКСТ ПО КНОПКЕ ПРИМЕНЯЕТСЯ НА ВЫДЕЛЕННОМ ТЕКСТЕ, НО СБРАСЫВАЕТСЯ ПРИ ПУБЛИКАЦИИ.
Изменение репутации для пользователя Stea1ch
Stea1chOffline
Сообщение №1756
написано: 25 ноября 2022, 02:34
| Отредактировано: Stea1ch - 25 ноября 2022, 03:03
Эх... рано радовался... где-то накосячил и теперь если я пытаюсь взять из ящика одну или несколько мин - получаю стойкий вылет... Более того! Вылет происходит даже если я пытаюсь положить мину в любой контейнер... В чем может быть проблема? Скрипт на мине такой:
scn C4SCRIPT
Begin OnDrop
placeatme C4Activator
disable
markfordelete
end
Не, не накосячил. Переделал все с нуля в отдельный мод только с этой миной - эффект тот же. Но если отвязать от мины этот скрипт - мины складируются и берутся нормально. Ничего не понимаю... HELP ME!!!!!
Изменение репутации для пользователя YikxX
YikxXOffline
Сообщение №1758
написано: 25 ноября 2022, 10:26
| Отредактировано: YikxX - 25 ноября 2022, 10:30
Как ни странно - да, хоть я там и был. Всего лишь OnDrop player и вылета больше нет. Но один фиг это баг! Причем тут OnDrop и контейнеры? Нигде об этом ни слуху ни духу, однако вот!
OnDrop ContainerRefID (optional) Run once when object is dropped from Container. - но в моем случае именно дроп не выполнялся - вылет был даже когда я пытался положить мину в контейнер. Это что, когда я беру что-то из контейнера, выполняется Drop-Add а не {ContainerRef}.RemoveItem {id}{count} player?
Уж сколько раз твердили миру: не объявляй переменных в результ-скрипте, не объявляй переменных в результ-скрипте... Тем более DoOnce. Эт'ж результ-скрипт, обернулся один раз - и всё. Конечно, она не работает. Есть же столько хороших мест, чтоб объявить переменные: квесты, реф-копии, раздел глобальных переменных (глобально для DoOnce, конечно, жирно). Объявил где следует - и обращайся к ней из любого другого места сколько влезет.
AnotherJupiter, да это не я ) Человек в моде одном увидел, у меня спросил. Там при прочтении терминала доб. скрытый перк, по наличию которого потом появляется строчка в диалоге. У него строчка не появилась, теперь понятно почему.
Я и сам не понял, нафиг автор мода обернул player.addperk в условие DoOnce, смысла в этом ровно 0 - добавляй хоть 100 раз, лишних перков или их дублей все равно неп появится )
Изменение репутации для пользователя AnotherJupiter
Ну, вообще иногда такие переменные работают. А иногда они не работают. Там какая-то сложная фигня, связанная с тем, что неименованные скрипты в игре на самом деле как-то привязаны к именованным, и могут их поломать и сами поломаться. Это надо в сообщениях Ипатова искать, он, кажется, объяснял. А я потом, как щас вспомнил, пытался коряво в меру разумения пересказать в "Картотеке".
AnotherJupiter, ну, что "иногда" - в этом и проблема. Надо, чтобы всегда. Видимо, если у тебя и так достаточно скриптов таких крутится в игре (моды и т.п.), то сбои и происходят. На ванили может и работает, кто знает...