1. Уважаемые гости и новички, приветствуем Вас на нашем форуме
    Здесь вы можете найти ответы практически на все свои вопросы о серии игр «Готика» (в том числе различных модах на нее), «Ведьмак», «Ризен», «Древние свитки», «Эра дракона» и о многих других играх. Можете также узнать свежие новости о разработке новых проектов, сыграть в увлекательные ФРПГ, восхититься творчеством наших форумчан, либо самим показать, что вы умеете. Ну и наконец, можете обсудить общие увлечения или просто весело пообщаться с посетителями «Таверны».

    Чтобы получить возможность писать на форуме, оставьте сообщение в этой теме.
    Удачи!
    Скрыть объявление
  2. Внимание!
    — Требуется примерно по 3-5 человек на каждую из версий ОС:: - Windows® XP SP3, Windows® Vista SP2, Windows® 7 SP1, Windows® 8, Windows® 8.1, Windows® 10(build 10 1607) и Windows® 10(build 10 1703). Для стационарных ПК и ноутбуков. Заявку на участие можно оставить здесь...
    Скрыть объявление

Полезные советы

Тема в разделе "Модостроение", создана пользователем GeorG, 12 май 2009.

Модераторы: Marvіn, MEG@VOLT
  1. Myxomop

    Myxomop

    Регистрация:
    28 май 2005
    Сообщения:
    2.485
    Благодарности:
    1.850
    Баллы:
    355
    Пол:
    Мужской
    Комфортная работа в Spacer для Г1 и Г2а на современном компьютере.

    Зачастую при работе в Spacer на современном мощном железе количество кадров в секунду (FPS) зашкаливает до 1000, от чего Spacer начинает безбожно глючить и перемещение или поворот камеры по локации происходит рывками, в худшем случае до полного зависания Spacer.

    Чтобы этого не происходило нужно ограничить FPS, к примеру до 60 запуская Spacer с параметром -zMaxFramerate:60

    Можно создать .cmd или .bat файл со следующим содержимым:
    Код (Text):
    @echo off
    start Spacer2.exe -zMaxFramerate:60
    Либо создать ярлык для Spacer и дописать -zMaxFramerate:60 в свойствах ярлыка в поле "Объект"
     
  2. clumb

    clumb Участник форума

    Регистрация:
    21 июн 2010
    Сообщения:
    294
    Благодарности:
    12
    Баллы:
    180
    Атака левого перса на другого.
    И так для этого нам надо создать ZS функцию:
    1. Открывает файл "Та" и там пишем.
    func void ta_atack(var int start_h,var int start_m,var int stop_h,var int stop_m,var string waypoint)
    {
    TA_Min (self, start_h, start_m, stop_h, stop_m, zs_atack, waypoint);
    };

    2. Создаем функцию

    func void zs_atack()
    {
    AI_SetWalkMode (self, NPC_RUN);
    AI_GotoWP (self, "OW_PATH_1_5_B");
    };

    func void zs_atack_loop()
    {
    Npc_SetTarget (self, Nov_5048_Lutians);
    AI_Attack (self);
    AI_FinishingMove (self, Nov_5048_Lutians);
    };

    func void zs_atack_end()
    {
    Npc_ExchangeRoutine (self, "START");
    };


    Компилим, ну и всё будет готово, мы создали функцию расписания для убийства левого перса левым персом, для атаки надо прописать изменение распорядка.
     
  3. Мільтен

    Мільтен Участник форума

    Регистрация:
    27 июн 2008
    Сообщения:
    824
    Благодарности:
    1.054
    Баллы:
    265
    Пол:
    Мужской
    То есть все будут атаковать непися с инстанцией Nov_5048_Lutians?:)
     
  4. clumb

    clumb Участник форума

    Регистрация:
    21 июн 2010
    Сообщения:
    294
    Благодарности:
    12
    Баллы:
    180
    Да, но атаковать будет один только тот НПС у которого в расписании стоит ta_atack
     
  5. kraw

    kraw
    Модостроитель

    Регистрация:
    11 окт 2005
    Сообщения:
    1.884
    Благодарности:
    826
    Баллы:
    275
    Пол:
    Мужской
    Тогда лучше брать не конкретного персонажа, а заносить его в переменную. Чтобы функция была универсальной.
     
  6. Мільтен

    Мільтен Участник форума

    Регистрация:
    27 июн 2008
    Сообщения:
    824
    Благодарности:
    1.054
    Баллы:
    265
    Пол:
    Мужской
    Это понятно. Я пробовал раньше что-то такое написать, правда тогда знаний было маловато:-\

    Вот об этом я и говорю.

    Хочу еще спросить, вот этот кусок:

    Npc_SetTarget (self, Nov_5048_Lutians);
    AI_Attack (self);
    AI_FinishingMove (self, Nov_5048_Lutians);

    Первая строка - выбор НПС-цели.
    Вторая - атака выбранного непися.
    Третяя - добивание непися.

    А если цель не потеряет сознание от одного удара, как тогда агрессор добьет ее?
    Или строка с добиванием попросту проигнорируется, если непись-цель не упал?

    И вот это:

    func void zs_atack_end()
    {
    Npc_ExchangeRoutine (self, "START");
    };

    Непись начинает выполнять распорядок дня "START"... а если тот распорядок, который он выполнял до нападения называется не "START"? Тогда изменение распорядка может быть немного не в тему...
    Просветите, если я заблуждаюсь.*flowers*
     
  7. kraw

    kraw
    Модостроитель

    Регистрация:
    11 окт 2005
    Сообщения:
    1.884
    Благодарности:
    826
    Баллы:
    275
    Пол:
    Мужской
    Более того, а если тот персонаж уже убит? А что будет при повторной загрузке сохранения? и т. п.
     
  8. clumb

    clumb Участник форума

    Регистрация:
    21 июн 2010
    Сообщения:
    294
    Благодарности:
    12
    Баллы:
    180
    Причем тут один удар? Он будет его ударять пока тот не упадет, но для этого лучше что бы и тот НПС напал на него.

    Товариство "Просвіта" просвещает, в скрипте ошибка (FACEPALM), вот запиливаю подправленный скрипт.

    func void zs_atack()
    {
    AI_SetWalkMode (self, NPC_RUN);
    AI_GotoWP (self, "OW_PATH_1_5_B");
    };

    func void zs_atack_loop()
    {
    if (Npc_IsDead (Nov_5048_Lutians))
    {
    AI_RemoveWeapon (self);
    Npc_ExchangeRoutine (self, "START");
    AI_ContinueRoutine (self);
    }
    else
    {
    Npc_SetTarget (self, Nov_5048_Lutians);
    AI_Attack (self);
    AI_FinishingMove (self, Nov_5048_Lutians);
    };
    };

    func void zs_atack_end()
    {
    };


    Bump:
    Не понял вопроса.
     
  9. Мільтен

    Мільтен Участник форума

    Регистрация:
    27 июн 2008
    Сообщения:
    824
    Благодарности:
    1.054
    Баллы:
    265
    Пол:
    Мужской
    Вот эта функция: func void zs_atack_loop()
    повторяется до выхода из состояния. Выбирается цель, потом она атакуется и добивается. Но если цель атакована, это не значит, что она убита. НПС-убийца может подбежать, ударить НПС-цель один раз и не убить его за этот удар. А непись-цель уже будет считатся атакованым. Тогда НПС-убийце надо будет его добить. Как НПС-убийца должен отреагировать на команду AI_FinishingMove, если непись, которого он должен убить еще даже не упал на землю?

    Если я правильно понял, Kraw интересуется, что произойдет, если непись-цель умрет сразу(то есть без добиваний).

    А с чего бы неписю-убийце идти на этот вейпоинт?*???*

    И Kraw прав: лучше указывать переменную, а не конкретного непися. А то пользы от этого состояния будет немного...
     
  10. Dimus

    Dimus ★★★★★★★
    Модератор

    Регистрация:
    19 июл 2010
    Сообщения:
    3.959
    Благодарности:
    2.245
    Баллы:
    540
    Пол:
    Мужской
    Кстати, а нужно ли добивание? Не проще ли прописать для жертвы
    Открыть спойлер
    aivar[AIV_DropDeadAndKill] = TRUE;

    Тогда жертва умрёт, если в результате боя её здоровье уйдёт в ноль.
     
  11. clumb

    clumb Участник форума

    Регистрация:
    21 июн 2010
    Сообщения:
    294
    Благодарности:
    12
    Баллы:
    180
    Я просто стал замечать, что если НПС стоит далеко, то Обычная функция атаки не работает, НПС начинает бежать, а потом просто убирает оружие и разворачивается и никого не мочит, для этого я прописал этот скрипт, что бы НПС всё таки добежал до ВП и убил нужного перса. А на этом вейпоинте стоял НПС, которого надо было убить (это всё дела из моего мода(.
    Да сэтой функцией иногда бывает прикол, что убийца просто подбегает и делает AI_finishindMove, для того что бы всё сработало как надо, нужно чтобы НПС атакованый, тоже начал атаковать убийцу, тогда всё будет правильно и убийца сначала побьет жертву, а потом убьёт.
    Это функция для Г1, а такое (что непися убили без добивания, как бандита из Аддон) в Г1 не возможно (по крайней мере я такое не встречал).
    В г1 такого вроде нет, а функция для Г1. А может и есть, но по моиму, так интересней.
    И повторяю, это функция для Г1.

    З.Ы. И последнее по вопросу Kraw если НПС уже мертв, то в функции прописан скрипт
    if (Npc_IsDead (Nov_5048_Lutians))
    {
    AI_RemoveWeapon (self);
    Npc_ExchangeRoutine (self, "START");
    AI_ContinueRoutine (self);

    CountinurRoutine можно и убрать, разницы не будет.
     
  12. Dimus

    Dimus ★★★★★★★
    Модератор

    Регистрация:
    19 июл 2010
    Сообщения:
    3.959
    Благодарности:
    2.245
    Баллы:
    540
    Пол:
    Мужской
    2 clumb:
    Ладно, тогда попробуем воспользоваться стандартными возможностями скриптов G1 - согласно скрипта AI\ZS_Human\ZS_Attack.d неписи добивают лежачих, если у них прописано враждебное отношение к этому персу:
    Следовательно, у атакующего нужно прописать враждебное отношение к жертве. Но действуют ли эти отношения для NPC - NPC или только для ГГ - NPC? Или же для подобного взаимодействия нужно прописывать враждебные отношения между гильдиями, к которым принадлежат убийца и его жертва?*???*
     
  13. George_M

    George_M Участник форума

    Регистрация:
    17 дек 2010
    Сообщения:
    682
    Благодарности:
    274
    Баллы:
    255
    Dimus, такой вариант действует, но лучше ставить Npc_GetTempAttitude и приказ атаковать нужную жертву чтобы после убийства все вернулось на круги своя. Это было предложено clumb-у в другой теме. Конечно если неписи разнесены далеко, то атакующий просто обламается бежать, но ведь ничто не мешает изменить ему время, после которого он бросает преследование. Или просто (поменяв self и other) и задав при желании дополнительно переход на бег:
    AI_GotoNpc (self,other);
    Npc_SetTempAttitude (self, ATT_HOSTILE);
    Npc_SetTarget (self,other);
    AI_StartState (self,ZS_ATTACK,1,"");
     
  14. Saturas

    Saturas
    Модостроитель

    Регистрация:
    11 фев 2009
    Сообщения:
    1.935
    Благодарности:
    639
    Баллы:
    275
    Пол:
    Женский
    Вот вам совет по спейсеру

    Если, вам вдруг где либо необходимо поставить много обьектов(на пример там кроватей, и прочих вобов)

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

    Вот собсно пример, как именно пользоватся этой функицей.

    Для начала включаем "Locial VobEdit PropertyPage"
    как показано на рисунке ниже.
    [​IMG]
    Дальше идем во вкладку "Object Pages" и видим там следующее:
    [​IMG]
    Немного предыстории:​

    У меня есть воб типа zCVob с визуализацией BEDHIGH_PSI.ASC(кровать)
    Естественно на этой кровати нельзя спать, изза того что для кроватей и прочих "интерактивных" объектов, необходимо что-бы класс объекта был дочерним от класса "oCMobBed" Так как же нам поменять класс с zCVob на oCMobInter, не удаляя уже существующий объект?
    Для этого нам и понадобится Locial VobEdit PropertyPage(описанный выше)
    И так рассмотрим работу с Locial VobEdit PropertyPage:
    С самого начала, нам необходим выпадающий список напротив кнопки "old"
    Кликаем по нему и выбираем тип изменяемого объекта, в нашем случае это zCVob(самая первая строчка в списке)
    Далее идем ниже, как показано на рисунке:
    [​IMG]
    Дважды кликаем(обязательно!) по полю "Visual" и вписываем в поле название визуализации изменяемых объектов(будут изменены ВСЕ объекты у которых параметры совпадут с параметрами, которые указанны в Locial VobEdit PropertyPage)
    Чтобы получилось как на рисунке ниже:
    [​IMG]

    На этом с настройками изменяемых объектов*flowers*

    Далее в томже окне наживаем на кнопку "old" и на ее месте появится кнопка с надписью "new"
    Ниже станет доступным второй выпадающий список, как на рисунке ниже:
    [​IMG]
    И выбираем в этом списке тип объекта "oCMobBed"
    И далее нажимаем кнопку "Start"
    Программа начнет поиск вобов с Visual:BEDHIGH_PSI.ASC
    И если таковы будут найдены, то изменит их класс с zCVob на "oCMobBed"
    По сути все, если же у вас много кроватей(допустим город в котором много домов)
    То можно проделать еще и такую операцию:
    Жмем кнопку "old" выбираем тип объекта oCMobBed
    Далее дважды кликаем по Vob-Visual и удаляем слово BEDHIGH_PSI.ASC (это для того чтобы изменения коснулись ВСЕХ объектов типа oCMobBed)
    Дальше раскрываем вкладку MOB и в ней, дважды кликаем по параметру "focus name"
    и вписываем туда MOBNAME_BED (при появлении объекта в фокусе выведется слово "Кровать")
    И чуть ниже в строке onStateFunc пишем SLEEPABIT(Не забываем перед тем как писать ДВАЖДЫ кликнуть по нужной строке!!!!!)
    [​IMG]

    ВНИМАНИЕ!​

    При двойном клике "Изменяемого объекта" (то есть кнопка слева вверху называется "old" слева от редактируемого параметра появится значек *, если-же при редактировании объекта который мы хотим получить из исходного (кнопка слева вверху нажа и называется "new") То в редактируемой строке появится значек -> Это можно увидить на картинках.

    Вроде бы все, ах да чуть не забыл, этимже способом можно выставлять такие параметры как cdDyn и тд просто после нажатия кнопки "new" в свойствах -vob меняем эти параметры как вам угодно.

    Bump: Зыы Если в строке "convert to new vobs" выбрать "Replace with Zenfile" и выбрать нужный вам Vobtree(как например фонари в хоринисе) то вместе заменяемых объектов будут появлятся нужные вам "Vobtree"*flowers*

    Bump: Вот еще один немало важный момент.
    Если у вас большая карта и на ней много вобов(не только тех которые вы меняете)
    То во время процесса поиска и замены, спейсер может подвиснуть - это не страшно, все станет вновь норм когда процесс завершится. И советую во время процесса на компе ничего не делать=)
     
  15. clumb

    clumb Участник форума

    Регистрация:
    21 июн 2010
    Сообщения:
    294
    Благодарности:
    12
    Баллы:
    180
    Только ГГ-НПС, подругому вроде никак=(
    Я этот скрипт проверял и неоднократно, к сожалению, это не работает, ATT_HОSTILE сработает на ГГ, как не крути((
     
  16. maggi1221

    maggi1221 Участник форума

    Регистрация:
    7 окт 2010
    Сообщения:
    182
    Благодарности:
    2
    Баллы:
    165
    Saturas, у меня не работает пакетная обработка, описанная 1 постом выше...

    old:
    класс zCVob, устанавливаю параметры поиска, а именно: поиск по visual (звездочка есть, название введено верно), далее перехожу на

    new:
    выставляю там класс oCMobInter, но в нем нет доп. полей для редактирования этого MOB...

    upd: проблема решена, Плитки (STOVE_NW_CITY_01.ASC), которые я искал имеют класс oCMobInter, поэтому, если нужно приписать всем плиткам скрипт, нужно чтобы и вверху и внизу был класс oCMobInter, в верхней строчке в подклассе Vob выделяем visual, убеждаемся что это модель плитки, идем в нижнюю строчку, двойной клик по onState ввод названия функции (без _s1), далее кнопка "старт"...
     
  17. Saturas

    Saturas
    Модостроитель

    Регистрация:
    11 фев 2009
    Сообщения:
    1.935
    Благодарности:
    639
    Баллы:
    275
    Пол:
    Женский
    Вот, яже говорил что у тебя мозг в нужную сторону варит=)
    Задал вопрос, а сам пытаешся егго решить своими руками, респект одним словом*flowers*
     
  18. maggi1221

    maggi1221 Участник форума

    Регистрация:
    7 окт 2010
    Сообщения:
    182
    Благодарности:
    2
    Баллы:
    165
    функция Wld_InsertNpc после своей работы оставляет валидный указатель self.

    зная это, создал следующую функцию:

    Открыть спойлер
    func void Wld_InsertNpcLoc(var int npc, var string spawnpoint, var int loc)
    {
    var string concatText;

    Wld_InsertNpc(npc, spawnpoint);
    self.aivar[AIV_LocationID] = loc;

    concatText = ConcatStrings(self.name[0], ", ");
    concatText = ConcatStrings(concatText, IntToString(loc));
    self.name[0] = concatText;
    };


    тест показывает, что все работает как надо.

    Где это может пригодится?
    у вас есть инстанция существа, а вы хотите сделать несколько копий существ в мире, но с незначительными изменениями...
    Пример: необходимо вставить в мир стаю обычных волков (5 шт) около трупа охотника, причем у одного из волков 50% хп.
     
  19. DenZanuda

    DenZanuda
    Архивариус

    Регистрация:
    4 ноя 2011
    Сообщения:
    815
    Благодарности:
    657
    Баллы:
    245
    Пол:
    Мужской
    пользуется ли кто-нибудь советом товарища GeorG в шапке темы?

    не могли бы вы продублировать тут текст ".CMD" файла, поскольку в оригинале затесались лишние символы?

    заранее спасибо *flowers*
     
  20. redleha

    redleha
    Модостроитель

    Регистрация:
    26 фев 2008
    Сообщения:
    697
    Благодарности:
    658
    Баллы:
    245
    Пол:
    Мужской
    DenZanuda, у меня свой, его покажу, различий мало, разве что vm-скрипт создаётся автоматом:
    Открыть спойлер

    @echo off
    echo copy /y "d:\GothicSourcer V3.14\Gothic Projects\SolDarkSaga\PrjGothic\gothic.dat" c:\games\MaterialFor_DarkSaga\MOD_main\_WORK\DATA\SCRIPTS\_COMPILED
    echo copy /y "d:\GothicSourcer V3.14\Gothic Projects\SolDarkSaga\PrjPARTICLEFX\PARTICLEFX.dat" c:\games\MaterialFor_DarkSaga\MOD_main\_WORK\DATA\SCRIPTS\_COMPILED
    echo copy /y "d:\GothicSourcer V3.14\Gothic Projects\SolDarkSaga\PrjMusic\Music.dat" c:\games\MaterialFor_DarkSaga\MOD_main\_WORK\DATA\SCRIPTS\_COMPILED
    echo copy /y "d:\GothicSourcer V3.14\Gothic Projects\SolDarkSaga\PrjMenu\Menu.dat" c:\games\MaterialFor_DarkSaga\MOD_main\_WORK\DATA\SCRIPTS\_COMPILED
    echo copy /y "d:\GothicSourcer V3.14\Gothic Projects\SolDarkSaga\PrjSFX\SFX.dat" c:\games\MaterialFor_DarkSaga\MOD_main\_WORK\DATA\SCRIPTS\_COMPILED
    echo copy /y "d:\GothicSourcer V3.14\Gothic Projects\SolDarkSaga\PrjFight\Fight.dat" c:\games\MaterialFor_DarkSaga\MOD_main\_WORK\DATA\SCRIPTS\_COMPILED
    echo copy /y "d:\GothicSourcer V3.14\Gothic Projects\SolDarkSaga\PrjVisualFX\VisualFX.dat" c:\games\MaterialFor_DarkSaga\MOD_main\_WORK\DATA\SCRIPTS\_COMPILED
    echo copy /y "d:\GothicSourcer V3.14\Gothic Projects\SolDarkSaga\PrjGothic\ou.bin" c:\games\MaterialFor_DarkSaga\MOD_main\_WORK\DATA\SCRIPTS\CONTENT\CUTSCENE
    c:
    cd \games\MaterialFor_DarkSaga
    echo [BEGINVDF]>>Dark_Saga_main.VM
    echo ^Comment=Мод "Темная Сага" команды "SAGA-Team" %%%N%%%NCopyright (c) "SAGA-Team" 2009 - 2011. %%%N%%%N^All rights reserved. %%%%N^Использование материалов мода без письменного согласия авторов ЗАПРЕЩЕНО! >> Dark_Saga_main.VM
    echo BaseDir=C:\games\MaterialFor_DarkSaga\MOD_main>>Dark_Saga_main.VM
    echo VDFName=C:\games\MaterialFor_DarkSaga\DarkSaga.mod>>Dark_Saga_main.VM
    echo [FILES]>>Dark_Saga_main.VM
    echo _WORK\*.* -r>>Dark_Saga_main.VM
    echo [EXCLUDE]>>Dark_Saga_main.VM
    echo [INCLUDE]>>Dark_Saga_main.VM
    echo [ENDVDF]>>Dark_Saga_main.VM
    GothicVDFS.exe /b .\Dark_Saga_main.VM
    del Dark_Saga_main.VM >nul
    exit


    Кавычки употребляются, когда адрес содержит пробелы и вроде если русские символы.
     
Модераторы: Marvіn, MEG@VOLT

Поделиться этой страницей