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

    Чтобы получить возможность писать на форуме, оставьте сообщение в этой теме.
    Удачи!

Туториал по использованию MOB для производства различных предметов.

Dimmell

Участник форума
Регистрация
23 Ноя 2008
Сообщения
2.899
Благодарности
111
Баллы
285
Туториал по использованию MOB для производства различных предметов.
Решил написать маленькое руководство по использованию MOB для производства различных предметов.
Скриптовая заготовка взята из демо-мода Xeres.
Для начала создаем в скриптах файл herd_s1.d функции диалога с MOB примерно такого содержания (можно добавить в существующие, например, Goldhacken.d):
Daedalus:
func void herd_s1()
{
    var C_Npc her;
    her = Hlp_GetNpc(PC_Hero);
    if(Hlp_GetInstanceID(self) == Hlp_GetInstanceID(her))
    {
        self.aivar[AIV_INVINCIBLE] = TRUE;
        PLAYER_MOBSI_PRODUCTION = MOBSI_HERD;
        AI_ProcessInfos(her);
    };
};


instance PC_HERD_FISCHBRATEN(C_Info)
{
    npc = PC_Hero;
    nr = 1;
    condition = pc_herd_fischbraten_condition;
    information = pc_herd_fischbraten_info;
    permanent = 1;
    important = 0;
    description = "Жарить рыбу (1x порция)";
};


func int pc_herd_fischbraten_condition()
{
    if((PLAYER_MOBSI_PRODUCTION == MOBSI_HERD) && (Npc_HasItems(hero,ItFo_Fish) >= 1))
    {
        return 1;
    };
};

func void pc_herd_fischbraten_info()
{
    Npc_RemoveInvItems(hero,ItFo_Fish,1);
    CreateInvItems(hero,itfo_fish_gebraten,1);
    CreateInvItems(hero,ItMi_Pan,1);
    Npc_RemoveInvItems(hero,ItFoMutton,1);
    b_endproductiondialog();
};


instance PC_HERD_FLEISCHBRATEN(C_Info)
{
    npc = PC_Hero;
    nr = 1;
    condition = pc_herd_fleischbraten_condition;
    information = pc_herd_fleischbraten_info;
    permanent = 1;
    important = 0;
    description ="Жарить мясо (1x порция)";
};


func int pc_herd_fleischbraten_condition()
{
    if((PLAYER_MOBSI_PRODUCTION == MOBSI_HERD) && (Npc_HasItems(hero,ItFoMuttonRaw) >= 1))
    {
        return 1;
    };
};

func void pc_herd_fleischbraten_info()
{
    Npc_RemoveInvItems(hero,ItFoMuttonRaw,1);
    CreateInvItems(hero,ItFoMutton,1);
    CreateInvItems(hero,ItMi_Pan,1);
    Npc_RemoveInvItems(hero,ItFoMutton,1);
    b_endproductiondialog();
};


instance PC_HERD_WANZENFLEISCHBRATEN(C_Info)
{
    npc = PC_Hero;
    nr = 1;
    condition = pc_herd_wanzenfleischbraten_condition;
    information = pc_herd_wanzenfleischbraten_info;
    permanent = 1;
    important = 0;
    description ="Жарить мясо жука (1x порция)";
};


func int pc_herd_wanzenfleischbraten_condition()
{
    if((PLAYER_MOBSI_PRODUCTION == MOBSI_HERD) && (Npc_HasItems(hero,ItAt_Meatbugflesh) >= 1))
    {
        return 1;
    };
};

func void pc_herd_wanzenfleischbraten_info()
{
    Npc_RemoveInvItems(hero,ItAt_Meatbugflesh,1);
    CreateInvItems(hero,itat_meatbugflesh_gebraten,1);
    CreateInvItems(hero,ItMi_Pan,1);
    Npc_RemoveInvItems(hero,ItFoMutton,1);
    b_endproductiondialog();
};


instance PC_HERD_EXIT(C_Info)
{
    npc = PC_Hero;
    nr = 1;
    condition = pc_herd_exit_condition;
    information = pc_herd_exit_info;
    permanent = 1;
    important = 0;
    description = Dialog_Ende;
};


func int pc_herd_exit_condition()
{
    if(PLAYER_MOBSI_PRODUCTION == MOBSI_HERD)
    {
        return 1;
    };
};

func void pc_herd_exit_info()
{
    CreateInvItems(hero,ItMi_Pan,1);
    Npc_RemoveInvItems(hero,ItFoMutton,1);
    b_endproductiondialog();
};

Прописываем в AI_Constants.d const int MOBSI_HERD = 9 ( 9 - следующее неиспользуемое значение const int MOBSI_HERD).
Вызов функции herd прописываем в свойствах MOB (в данном случае плиты STOVE) в *.ZEN в Спейсере или !нагло! открыв любой готовый *.ZEN в блокноте не портящем кодировку (я использовал Notepad++):
Daedalus:
    % oCMobInter:eek:CMOB:zCVob 35585 1007]
            pack=int:0
            presetName=string:
            bbox3DWS=rawFloat:25213.7305 4433.24316 -5755.69092 25326.6738 4663.24316 -5642.74609
            trafoOSToWSRot=raw:66827dbf0000000099830ebe000000000000803f0000000099830e3e0000000066827dbf
            trafoOSToWSPos=vec3:25270.2012 4433.24219 -5699.21924
            vobName=string:
            [B]visual=string:STOVE_NW_CITY_01.ASC[/B]
            showVisual=bool:1
            visualCamAlign=enum:0
            visualAniMode=enum:0
            visualAniModeStrength=float:0
            vobFarClipZScale=float:1
            cdStatic=bool:0
            cdDyn=bool:1
            staticVob=bool:1
            dynShadow=enum:0
            zbias=int:0
            isAmbient=bool:0
            [visual zCModel 0 1008]
            []
            [ai % 0 0]
            []
            focusName=string:
            hitpoints=int:10
            damage=int:0
            moveable=bool:0
            takeable=bool:0
            focusOverride=bool:0
            soundMaterial=enum:0
            visualDestroyed=string:
            owner=string:
            ownerGuild=string:
            isDestroyed=bool:0
            stateNum=int:1
            triggerTarget=string:
            [COLOR=red][B]useWithItem=string:ItMi_Pan[/B][/COLOR]
            conditionFunc=string:
            [COLOR=red][B]onStateFunc=string:Herd[/B][/COLOR]
            rewind=bool:0

Строка useWithItem=string:ItMi_Pan определяет что использование MOB возможно только при наличии сковородки (ItMi_Pan) в инвентаре ГГ, строка onStateFunc=string:Herd (именно Herd, а не herd_s1 !!!) вызывает функцию herd_s1(). Сохраняем изменения.
Прописываем недостающие инстанции itfo_fish_gebraten и itat_meatbugflesh_gebraten для жареных рыбы и жука в IT_Food.d:
Daedalus:
instance ITFO_FISH_GEBRATEN(C_Item)
{
    name = "Поджаренная рыба";
    mainflag = ITEM_KAT_FOOD;
    flags = ITEM_MULTI;
    value = Value_FishSoup;
    visual ="ItFo_Fish.3DS";
    material = MAT_LEATHER;
    scemeName ="FOODHUGE";
    on_state[0] = use_fish_gebraten;
    description = name;
    text[1] = NAME_Bonus_HP;
    count[1] = HP_FishSoup;
    text[5] = NAME_Value;
    count[5] = Value_FishSoup;
};


func void use_fish_gebraten()
{
    Npc_ChangeAttribute(self,ATR_HITPOINTS,HP_FishSoup);
};


    instance ITAT_MEATBUGFLESH_GEBRATEN(C_Item)
{
    name = "Жареное мясо жука";
    mainflag = ITEM_KAT_FOOD;
    flags = ITEM_MULTI;
    value = Value_Meatbugflesh * 2;
    visual ="ItAt_Meatbugflesh.3DS";
    material = MAT_LEATHER;
    scemeName ="FOODHUGE";
    on_state[0] = use_meatbugflesh_gebraten;
    description = name;
    text[0] = "";
    text[1] = NAME_Bonus_HP;
    count[1] = 20;
    text[2] = "";
    text[3] = "";
    text[5] = NAME_Value;
    count[5] = value;
};


func void use_meatbugflesh_gebraten()
{
    Npc_ChangeAttribute(self,ATR_HITPOINTS,20);
};

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

Дополнение.
Во вложении скрипт с функциями жарки-варки из моего патч-мода 1.15.
Выкладываю как болванку для модов - облегчит прописывание функций.
В ЗЕНах:
Daedalus:
// - для плиты
useWithItem=string:ItMi_Pan
onStateFunc=string:Herd

// - для сковородки
useWithItem=string:ItFoMuttonRaw
onStateFunc=string:HerdPan

// - для котла
useWithItem=string:ITMI_SCOOP
onStateFunc=string:Kessel

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

PS. Инстанции пропишете сами. :)
 
Последнее редактирование модератором:

marazmus

★★★★★★★★★★★
Основатель
Регистрация
7 Янв 2003
Сообщения
2.117
Благодарности
912
Баллы
385
Клево, спасибо за статью :) Разрешаешь разместить на мод.вог.ру? Или можешь сам разместить, отпиши мне в личку, я открою там аккаунт редактора для тебя.
 

Feuermagier


Модостроитель
Регистрация
13 Апр 2008
Сообщения
932
Благодарности
130
Баллы
225
У меня вопрос: нужно ли добавлять какой либо невидимый обьект для предмета к которому я хочу создать диалог, если при этом данный предмет является частью меша мира?
 

Dimmell

Участник форума
Регистрация
23 Ноя 2008
Сообщения
2.899
Благодарности
111
Баллы
285
Feuermagier написал(а):
У меня вопрос: нужно ли добавлять какой либо невидимый обьект для предмета к которому я хочу создать диалог, если при этом данный предмет является частью меша мира?
Что значит "предмет является частью меша мира"?
Выдержка из"Сводная таблица объектов Спейсера"
oCMobInter (zCModel)

Применение - Объекты взаимодействия с персонажами (Кровать, наковальня, рунный стол, рычаг…)

Значимые опции
visual: *.asc, *.mds
cdDyn: TRUE - определение коллизий персонажей
focusName: отображаемое название, const string из скриптов
triggerTarget: имя виртуального объекта для посылки триггер-сигнала
useWithItem: имя инстанции, предмета, который должен быть в инвентаре, условие использования объекта
conditionFunc: скриптовая функция (которая возвращает 1 или 0), условие использования объекта
onStateFunc: скриптовая функция, выполняемая при использовании
rewind: TRUE - для посылки триггер-сигнала при каждом использовании
 
Последнее редактирование модератором:

GeorG

Участник форума
Регистрация
27 Авг 2008
Сообщения
3.447
Благодарности
11
Баллы
295
Dimmell
Что значит "предмет является частью меша мира"?
Видимо он хочет создать диалог с деревом (ну или типа того, скалой например, или с избушкой на курьих ножках :D), который является частью меша мира

Feuermagier Попробуй как не будь через скрипт-тригер
 
Последнее редактирование модератором:

Feuermagier


Модостроитель
Регистрация
13 Апр 2008
Сообщения
932
Благодарности
130
Баллы
225
Спасибо за ответ. Чтобы было понятнее: мне надо поставить несколько статуй, к которым открывается диалог вида:спросить - закончить и в следующей главе поднести\возложить - закончить.
 

MEG@VOLT

★★★★★★★★★
ТехАдмин
Регистрация
24 Мар 2006
Сообщения
9.106
Благодарности
6.070
Баллы
1.565
Ну нет проще варианта как этот:
Создаешь статую какую тебе надо, вставляешь ее в мир. а дальше лезешь в эту папку \Story\B_AssignAmbientInfos и по подобию одного из ассингов делаешь свой ассинг.
 

Feuermagier


Модостроитель
Регистрация
13 Апр 2008
Сообщения
932
Благодарности
130
Баллы
225
Дак статуи делать вобами, или аттачить к мешу локации?
 

GeorG

Участник форума
Регистрация
27 Авг 2008
Сообщения
3.447
Благодарности
11
Баллы
295
Feuermagier написал(а):
Дак статуи делать вобами, или аттачить к мешу локации?

А вот если честно, трудно посмотреть, как сделано в игре... Там статуи не являются частью меша локации... так в сто раз удобней и если она будит мешью, то как ты будишь к ней обращаться ::)
 
Последнее редактирование модератором:

Dimmell

Участник форума
Регистрация
23 Ноя 2008
Сообщения
2.899
Благодарности
111
Баллы
285
Дак статуи делать вобами, или аттачить к мешу локации?
Открываем, например, NEWWORLD.ZEN в блокноте, поиском MOBNAME_INNOS находим
[% oCMobInter:eek:CMOB:zCVob 35585 6949]
pack=int:0
presetName=string:
bbox3DWS=rawFloat:12577.7578 1554.4585 -22100.8438 12779.4121 1867.6145 -21975.5703
trafoOSToWSRot=raw:8c177e3f00000000a896f9bd000000000000803f00000000a896f93d000000008c177e3f
trafoOSToWSPos=vec3:12678.585 1555.05957 -22038.207
vobName=string:
visual=string:INNOS_NW_MISC_01.ASC
showVisual=bool:1
visualCamAlign=enum:0
visualAniMode=enum:0
visualAniModeStrength=float:0
vobFarClipZScale=float:2
cdStatic=bool:0
cdDyn=bool:1
staticVob=bool:1
dynShadow=enum:0
zbias=int:0
isAmbient=bool:0
[visual zCModel 0 6950]
[]
[ai % 0 0]
[]
focusName=string:MOBNAME_INNOS
hitpoints=int:10
damage=int:0
moveable=bool:0
takeable=bool:0
focusOverride=bool:0
soundMaterial=enum:0
visualDestroyed=string:
owner=string:
ownerGuild=string:
isDestroyed=bool:0
stateNum=int:1
triggerTarget=string:
useWithItem=string:
conditionFunc=string:
onStateFunc=string:prayShrine
rewind=bool:0
[]
Как делать в Спейсере я думаю поймешь ;)
 

Wallerstein

Участник форума
Регистрация
26 Апр 2009
Сообщения
965
Благодарности
23
Баллы
195
Спасибо за ответ, бум делать воб с диалогом. Кстати мир у нас полностью новый, ладно, подумаем еще. туторы почитаем, сделаем в общем.Всем спасибо! :)
 

Dimmell

Участник форума
Регистрация
23 Ноя 2008
Сообщения
2.899
Благодарности
111
Баллы
285
Добавил скрипт и описание в шапку.
 

AMARANT

Участник форума
Регистрация
12 Окт 2009
Сообщения
11
Благодарности
0
Баллы
150
Туториал отличный, но у меня почему-то если ничего не жаришь, а нажимаешь "КОНЕЦ", то все равно дается жареное мясо, но только в первом случае. Потом все нормально.
 

Pinic

Участник форума
Регистрация
14 Июн 2013
Сообщения
128
Благодарности
13
Баллы
185
Прописываем в AI_Constants.d const int MOBSI_HERD = 9 ( 9 - следующее неиспользуемое значение const int MOBSI_HERD).
А как это понять, что здесь надо прописывать для добычи руды?

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

Мільтен

Участник форума
Регистрация
27 Июн 2008
Сообщения
862
Благодарности
427
Баллы
265
Все разобрался и столкнулся с другой проблемой нечего не добывает нажимаю добывать руду а он пишит руда закончилась что делать?

1. Знаки препинания.
2. Полный алгоритм действий, скрины, скрипты в студию.
 

Pinic

Участник форума
Регистрация
14 Июн 2013
Сообщения
128
Благодарности
13
Баллы
185
2. Полный алгоритм действий, скрины, скрипты в студию.
Вот этот скрипт взял из мода Xeres и написал в свойствах MOB что надобыло
Все делал как было написано выше, диалог есть, а руды нет) Как это исправить?
 

Вложения

  • Skript.txt
    2,2 KB · Просмотры: 211
  • Svoystva.txt
    1 KB · Просмотры: 221

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.321
Благодарности
3.166
Баллы
525
Все делал как было написано выше, диалог есть, а руды нет) Как это исправить?

Если пишет "Руды больше нет.", то возможная причина в отсутствии вейпоинта "WP_ERZHACKEN_NW_01" рядом с рудной жилой. Этот вей прописан в функции b_erzmob_bestimmung из приведённого тобой скрипта.
 
Сверху Снизу