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

    Чтобы получить возможность писать на форуме, оставьте сообщение в этой теме.
    Удачи!
  • Друзья, доброго времени суток!
    Стартовал новый литературный конкурс от "Ордена Хранителей" - "Пираты Миртанского моря".
    Каждый может принять в нём участие и снискать славу и уважение, а в случае занятия призового места ещё и получить награду. Дерзайте
  • Дорогие друзья, год подходит к концу, и пришло время подвести его итоги и наградить достойных

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

Не стесняюсь спросить....

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
463
Благодарности
289
Баллы
230
Вопрос такой. В параметрах C_ITEM есть weigth (вес поидее), можно ли в игре сделать вес вещей более проще чем я это пробую сделать?
Я не знаю, будет ли этот код кому-то в пользу или во вред.
На всякий случай выложу пример расчёта веса предметов у персонажа.

1) Для определения численных границ идентификаторов предметов необходимо расставить два предмета - пустышки. Один, инстанция которого называется "It_StartIndex" - это самый первый предмет из всех предметов, имеющихся в проекте.
В данном случае помещаю его перед инстанцией "ItAm_Addon_Franco", вот так:

Код:
instance It_StartIndex(C_Item)
{
    mainflag = ITEM_KAT_NONE;
    flags = ITEM_NFOCUS;
};

instance ItAm_Addon_Franco(C_Item)
{
    name = NAME_Amulett;
    mainflag = ITEM_KAT_MAGIC;
    flags = ITEM_AMULET;
    value = Value_ItAm_Addon_Franco;
    visual = "ItAm_Hp_01.3ds";
    visual_skin = 0;
    material = MAT_METAL;
    on_equip = Equip_ItAm_Addon_Franco;
    on_unequip = UnEquip_ItAm_Addon_Franco;
    wear = WEAR_EFFECT;
    effect = "SPELLFX_ITEMGLIMMER";
    description = "Амулет Франко";
    text[2] = NAME_Bonus_Str;
    count[2] = STR_Franco;
    text[3] = NAME_Bonus_Dex;
    count[3] = DEX_Franco;
    text[4] = NAME_Bonus_HP;
    count[4] = HP_ItAm_Addon_Franco;
    text[5] = NAME_Value;
    count[5] = value;
    inv_zbias = INVCAM_ENTF_AMULETTE_STANDARD;
};
см. Items\IT_Addon_Amulette.d.

Второй же предмет, инстанция которого называется "It_EndIndex" помещается в конец всех предметов и оказывается последним или замыкающим предметом.
Код:
instance itmi_erolskelch(C_Item)
{
    name = "Поцарапанная серебряная чаша";
    mainflag = ITEM_KAT_NONE;
    flags = ITEM_MULTI;
    value = 125;
    visual = "ItMi_SilverChalice.3DS";
    material = MAT_METAL;
    description = name;
    text[5] = NAME_Value;
    count[5] = value;
};

instance It_EndIndex(C_Item)
{
    mainflag = ITEM_KAT_NONE;
    flags = ITEM_NFOCUS;
};
см. Items\MissionItems_Addon.d.

2)Далее в проекте создаём папку, например "TriggerScripts", а в ней скрипт - "TR_FINDWEIGHT.d" и пишем в нём следующий код в такой же последовательности:
Код:
var int Player_Tonnage;//Тоннаж игрока(вес переносимых вещей)
var int Item_StartIndex;//начальный индекс для поиска вещей
var int Item_EndIndex;//последний индекс для поиска вещей

//функция преобразования идентификаторов вещей в их инстанции
func int GiveInstance(var int id)
{
    return id;
};

//Стэковый цикл перебора индефикаторов всех вещей...
//...для поиска общего веса вещей персонажа
func void PC_FindWeight(var int id)
{
  
    var int itemInstance;
    itemInstance = GiveInstance(id);//по id получаем инстанцию предмета или 'не предмета'
  
    var int items;
    items = Npc_HasItems(hero,id);//по этому же id смотрим, имеются ли у ГГ такие вещи
  
  
    if (items > 0)//если таковые вещи имеются
    {
        //получаем ссылку на предметы
        Npc_GetInvItem(hero, itemInstance);
      
        //добавляем вес вещей
        Player_Tonnage = Player_Tonnage + items * item.weight;
    };
  
    //если счётчик не превышает допустимые пределы, то
    if (id < Item_EndIndex)
    {
        //продолжаем перебор (вызов функции из самой себя)
        PC_FindWeight(id + 1);
    };
  
    //иначе, обрываем цикл и выходим из функции
    return;
};



func void TR_FINDWEIGHT()//Trigger-script (Задержка = 1 сек.)
{
    var string str;
  
    //если индексы вещей не найдены, то
    if (Item_StartIndex == 0) || (Item_EndIndex == 0)
    {
        var C_NPC her;
      
        //создаём ссылку на игрока(используем инстанцию 'PC_Hero' по умолчанию)
        her = Hlp_GetNpc(PC_Hero);
      
        //создаём вещи у ГГ для определения индексов
        CreateInvItem(her,It_StartIndex);
        CreateInvItem(her,It_EndIndex);
      
        //находим индексы
        Item_StartIndex = Hlp_GetInstanceId(It_StartIndex);//начальный индекс поиска
        Item_EndIndex = Hlp_GetInstanceId(It_EndIndex);//окончательный индекс
      
        //удаляем вещи
        Npc_RemoveInvItem(her,It_StartIndex);
        Npc_RemoveInvItem(her,It_EndIndex);
    };
  
  
    Player_Tonnage = 0;//обнуляем значение веса предметов у игрока
    PC_FindWeight(Item_StartIndex);//находим вес предметов
  
    //объединение и вывод информации на экран
    str = IntToString(Player_Tonnage);
    str = ConcatStrings("Переносимый вес: ",str);
    str = ConcatStrings(str," ед.");
    PrintScreen(str,3,5,Font_ScreenSmall,2);
  
  
    Wld_SendTrigger("TR_FINDWEIGHT");//вызываем триггер
};

3) Триггер-скрипт вызывается в одной из функций инициализации локации, например, таком образом:
Код:
func void INIT_NEWWORLD_PART_CITY()
{
    Wld_SendTrigger("TR_FINDWEIGHT");
};
Где "NEWWORLD_PART_CITY" - название zen-уровня, на котором стартуем.

4) Функция "PC_FindWeight" имеет локальную переменную "itemInstance". Чтобы эта переменная хранила в себе ссылку на инстанцию, необходимо сделать кое-какие изменения в ходе компиляции проекта.
Для этого переходим в системную папку программы GothicSourcer V3.14.
В данном случае это: "С:\GothicSourcer V3.14\GothicSourcer\System\". Затем находим и открываем файл "RedefinedLocalVariable.dsc" любым текстовым редактором. Теперь нужно добавить в него следующую строчку:
Код:
int# PC_FindWeight.itemInstance;

Также, в этой папке находим и открываем файл "RedefinedFunc.dsc" и прописываем в нём следующую строчку:
Код:
int# GiveInstance(int);
Это нужно для того, чтобы функция "GiveInstance" принимала целочисленные значения, а возвращала результат в виде ссылки на инстанцию.

Всё, теперь можно использовать свойство weight у любых вещей, заключённых в искусственные рамки предметов "It_StartIndex" и "It_EndIndex" и определять общий вес вещей, переносимых персонажем PC_Hero.

Используемая программа: GothicSourcer 3.14
Использованные скрипты: Г2НВ.
Свойства триггер-скрипта см. во вложении.
 

Вложения

  • TR_FINDWEIGHT.jpg
    TR_FINDWEIGHT.jpg
    233,5 KB · Просмотры: 312

osipovjohn

Участник форума
Регистрация
11 Июл 2012
Сообщения
24
Благодарности
0
Баллы
160
А если я добавлял файлы итемов, изменял имеющиеся, переименовывал - как определить где первый и последний фаилы?
И еще один вопрос.
Как добавить тело триггера в ранее созданный зацикленный триггер, чтобы не трогать zen фаил?
 
Последнее редактирование:

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
463
Благодарности
289
Баллы
230
Как добавить тело триггера в ранее созданный зацикленный триггер, чтобы не трогать zen фаил?

Всё просто. Смотри, из примера выше:
func void TR_FINDWEIGHT()//название функции триггер-скрипта(см. вложение, поле "scriptFunc")
Wld_SendTrigger("TR_FINDWEIGHT");//название вызываемого триггер-скрипта(см. вложение, поле "VobName")
Переименовывай всё аналогично своему триггер-скрипту.
Да, в примере используется задержка, равная 1 сек (см. вложение, поле "fireDelaySec").


А если я добавлял файлы итемов, изменял имеющиеся, переименовывал - как определить где первый и последний фаилы?

Можно воспользоваться поиском по слову "instance".
FindInFiles.jpg

По окончанию поиска, в окне "Сообщения", можно увидеть в каких скриптах встречается это слово.
Там то и надо искать инстанцию первого предмета. Она должна выглядеть примерно так:
Код:
instance ItFo_Apple(C_Item)
Но надо быть внимательным! Инстанции не обязательно должны быть объявлены от класса "(C_ITEM)",
они могут быть также объявлены от прототипа "prototype", например, сначала объявляется сам
прототип от класса "C_ITEM":
Код:
prototype Prototype_StonePlate(C_Item)
а затем уже объявляется инстанция от этого прототипа:
Код:
instance ItWr_StrStonePlate1_Addon(Prototype_StonePlate)
И если такая инстанция встречается первее всех, значит нужно перед ней устанавливать вещь со
стартовым индексом.
Последний предмет находится таким же образом.

В скрипте "Classes.d", глобальную инстанцию "instance item(C_Item)" не бери во внимание. Она для
других целей.

Поэтому, как совет - держать все вещи в одной "упорядоченной кучке". Так будет проще и быстрей.
Ведь проще, когда всё лежит на своих местах и если сразу видно где начинаются инстанции предметов и где они заканчиваются. А быстрей, потому что таким образом уменьшается разброс порядковых номеров этих предметов, тем самым уменьшается область их поиска.
Что цикл был от 6000 до 8000(инстанции предметов упорядочены), а что будет от 6000 до 28000(инстанции объявлены в разброс). Разница есть. Тем более не надо забывать, что мы работаем со 'стэком', а захламлять его опасно.
Опасно тем, что в любой момент может произойти переполнение 'стэка'. Дальше последует ошибка и вылет из приложения. Хорошо, если это произойдёт во время тестов, а если нет? - кому-то будет не приятно.
Поэтому я сразу написал, что этот способ может быть кому-то в пользу, а кому-то во вред.

Не забывай!
Чтобы расчёт веса работал везде, необходимо также размещать по одному триггер-скрипту на каждую
отдельную локацию и также запускать его в функции инициализации этой отдельной локации.
 

osipovjohn

Участник форума
Регистрация
11 Июл 2012
Сообщения
24
Благодарности
0
Баллы
160
Ты красавчик) Все работает как часы!!!
 

DarkNazgul

Участник форума
Регистрация
12 Янв 2014
Сообщения
33
Благодарности
18
Баллы
160
Нужен совет знающих людей :) Допустим в максе у меня есть модель глорха с передними конечностями или курица с крыльями. Если я в максе клонирую 2 bip для для конечностей которых у них раньше не было, применяю физику, рисую анимацию. В самом максе все анимации проигрываются правильно, курица машет крыльями в различных случаях. Компилировал файлы. Курица повторяет все анимации, все кроме движений крыльев. Что то мне подсказывает что 2 новых bip которые я ввел, должны где то еще кроме ask файлов прописываться. Открывал блокнотом ask там все на месте.

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

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.411
Благодарности
3.242
Баллы
525
Что то мне подсказывает что 2 новых bip которые я ввел, должны где то еще кроме ask файлов прописываться. Открывал блокнотом ask там все на месте.

Иерархия костей фиксируется в файле *.MDH. Загляни Блокнотом туда, есть ли там новые кости. Но при изменении состава костей, если не путаю, придётся переделывать все анимации модели под новый скелет.

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

Не настолько продвинут, чтобы рассказать, как это сделать в Максе. На это есть туторы. Но можно "привязать" одну кость к другой в asc-исходнике с помощью того же Блокнота. Строка *NODE_PARENT "ХХХХХ" в свойствах кости указывает материнскую кость.
 

alex_draven


Модостроитель
Регистрация
13 Сен 2007
Сообщения
2.183
Благодарности
2.880
Баллы
420
При любом изменении конфигурации костей монстра необходимо его полностью перекомпилировать со всеми анимациями. ASC-анимации, полученные на одном наборе костей, не будут корректно работать с другим.
Что до добавления конечностей, то тут в целом просто: при наличии исходника скелета в формате caracter studio нужно перейти в figure mod, и добавить лапки с нужным количеством элементов (arm, hand, finger). Или прицепить bone-цепочки, если нужны дополнительные кости (крылья и прочее). Соответственно, слетит привязка шкуры монстра к скелету, поэтому необходима будет перенастройка модификатора physique или skin (если используется он). А после переделать все анимации на новом наборе на рабочем bip-скелете, экспортировав все обратно в ASC.
Исходники падальщика есть на wog.de. А вот с остальным беда - этого нет. ASC- это не исходник, а только результат компиляции максовского проекта монстра в виде текстового файла блокнота. Имхо, на нем ничего путного никогда не сделать.

В любом случае, монстра придется практически делать заново.
max_cfg.jpg
 
Последнее редактирование:

Defman

Участник форума
Регистрация
26 Май 2013
Сообщения
3.165
Благодарности
245
Баллы
300
Компиляция mrm файла возможна с помощью Spacer?
И можно ли посмотреть лог запуска мода? Поглядеть, что и откуда он загружает и т.д.
 

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.411
Благодарности
3.242
Баллы
525
Компиляция mrm файла возможна с помощью Spacer?

Её, по-хорошему, и нужно делать с помощью Спейсера. В этом случае в модели закрепляются свойства материалов из библиотек Спейсера. Только сначала нужно открыть 3ds-меш в Спейсере, уладить имеющиеся проблемы с материалами, если они есть, сохранить меш. После этого можно открывать ZEN и компилить модель. Если модель есть в мире, она скомпилится сразу, если её ещё нет, то нужно вставить.
 

DarkNazgul

Участник форума
Регистрация
12 Янв 2014
Сообщения
33
Благодарности
18
Баллы
160
У меня есть новая голова - подогнал под hum_head_bald закрыл шею, чуть подработал, сохранил в аск, в блокноте переписал всю шапку вместе c material list до самого mesh ( там уже пошли вершины и прочее от моей модели) загрузил голову в макс - кушать и болтать не хочет. Не дает даже загрузить анимации. Как ее наладить? :D
голва.jpg
 

Beowulf

Участник форума
Регистрация
21 Ноя 2010
Сообщения
1.956
Благодарности
1.490
Баллы
465
в блокноте переписал всю шапку вместе c material list до самого mesh
И зачем ты это делал? Надо непосредственно в максе покрыть текстурой модель, и анимировать ее.

Также должен быть создан файл вида X.MMS, где Х - название твоей головы
Примерный вид файла
Код:
morphMesh ("Hum_Head_ISLANDER")
{
    morphRef ("HUM_HEAD_ISLANDER.ASC")
    morphAni ("S_NEUTRAL" 1 1 -1 1 L "HUM_HEAD_ISLANDER.ASC" 0 0 SPD:1)
    morphAni ("T_EAT" 1 0.1 2 0.1 . "HUM_HEAD_ISLANDER_EAT.ASC" 0 5 SPD:10)
    morphAni ("T_HURT" 1 0.1 -1 0.1 L "HUM_HEAD_ISLANDER_EMOTIONS.ASC" 0 0 SPD:1)
    morphAni ("S_EYESCLOSED" 1 0.1 -1 0.1 L "HUM_HEAD_ISLANDER_EMOTIONS.ASC" 1 1 SPD:1)
    morphAni ("R_EYESBLINK" 4 0.04 0 0.04 . "HUM_HEAD_ISLANDER_EMOTIONS.ASC" 2 2 SPD:1)
}
 
Последнее редактирование:

DarkNazgul

Участник форума
Регистрация
12 Янв 2014
Сообщения
33
Благодарности
18
Баллы
160
Я не правильно сформулировал. Мне нужно заменить старую модель hum_head_bald новой, не меняя названия модели и текстуры. Дабы не лезть в скрипты. Подскажи пожалуйста как анимировать голову? анимации не загружаются...
 
Последнее редактирование:

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.411
Благодарности
3.242
Баллы
525
загрузил голову в макс - кушать и болтать не хочет. Не дает даже загрузить анимации.

Анимировать придётся заново. Родные анимации не прокатят. Они привязаны к тому количеству вершин, которое имеется в оригинальной модели. Собственно, это список положений вершин в отдельных кадрах анимации. А в твоей голове вершин явно больше. Кстати, сколько? Не уверен, что древний движок проглотит такое количество.
 

hell9999

Участник форума
Регистрация
12 Апр 2008
Сообщения
2.049
Благодарности
1.170
Баллы
340
Я не правильно сформулировал. Мне нужно заменить старую модель hum_head_bald новой, не меняя названия модели и текстуры. Дабы не лезть в скрипты. Подскажи пожалуйста как анимировать голову? анимации не загружаются...
Никак не получится. Даже добавив пару вершин к старой модели, морфинг уже не будет загружаться. Ибо это не скелетная анимация, и анимируются (суть записываются в файл) глобальные координаты перемещающихся вершин. Так что, новая голова - новая морфинговая анимация. В готике она довольно примитивна, так что можно за полчаса вручную двигая вертексы воссоздать все анимации буквально по кадрам.
 

DarkNazgul

Участник форума
Регистрация
12 Янв 2014
Сообщения
33
Благодарности
18
Баллы
160
ElderGamer глянь скрин) там цифрами указано количество. Систем пак меня уже давно выручает с полигонами, в разумных пределах конечно ) Hell спасибо! буду пробовать.
 

alex_draven


Модостроитель
Регистрация
13 Сен 2007
Сообщения
2.183
Благодарности
2.880
Баллы
420
Полигоны - это конечно хорошо. Но система освещения старая. Так вот, на высокополигональных моделях порой появляются крайне неприятные пятна теней в местах особых изгибов, впадин и прочей "детализации".
Поэтому лучше проверить, как оно на вид в игре.
 

DarkNazgul

Участник форума
Регистрация
12 Янв 2014
Сообщения
33
Благодарности
18
Баллы
160
Вопрос по материалам, если у модели монстра 2 текстуры, одна из них использует альфа канал. Пользовался вот этой статьей http://www.gothic-library.com/index/ispolzovanie_alpha_kanala_v_3d_studio_max/0-138 При экспорте в аск файле указывается такие строчки, как я понимаю они ничего не отражают из того что я сделал. И в игре зверушка бегает с дефолтной текстурой ((
*MATERIAL_LIST {
*MATERIAL_COUNT 1
*MATERIAL 0 {
*MATERIAL_NAME "MultiMtl #0"
*MATERIAL_CLASS "Multi/Sub-Object"
*NUMSUBMTLS 2
*SUBMATERIAL 0 {
*MATERIAL_NAME "0003_wolf"
*MATERIAL_CLASS "Standard"
*MATERIAL_DIFFUSE 1 1 1
*MAP_DIFFUSE {
*BITMAP "0003_animal_wolf.tga"
}
}
*SUBMATERIAL 1 {
*MATERIAL_NAME "0003_wolf_hair"
*MATERIAL_CLASS "Standard"
*MATERIAL_DIFFUSE 1 1 1
*MAP_DIFFUSE {
*BITMAP "0003_animal_wolf_fur.tga"
}
}
}
}
 

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.411
Благодарности
3.242
Баллы
525
Не совсем понял твою ситуацию, поскольку ты не делаешь различий между текстурой и материалом. Текстура - это картинка. Текстура может содержать альфа-канал - информацию о степени полупрозрачности пикселей. Но движок игры работает с материалами. Материал, кроме собственно текстуры, содержит информацию о некоторых свойствах, например, о полупрозрачности текстуры, используемой анимации и т.д. Для того, чтобы Спейсер при компиляции модели правильно подцепил все свойства материалов, описание материала должно находиться в библиотеке материалов Спейсера. Посмотри эту тему, возможно, она что-то подскажет.
 

DarkNazgul

Участник форума
Регистрация
12 Янв 2014
Сообщения
33
Благодарности
18
Баллы
160
В чем разница материала и текстуры я знаю)) Читал здесь туторы, не хватало только понимания почему все это не работает в готике. Спасибо! отличная статья, буду пробовать.
 

Orc Hunter


Модостроитель
Регистрация
12 Окт 2013
Сообщения
1.269
Благодарности
1.667
Баллы
305
У меня такой вопрос, можно-ли сделать так что при диалоге ГГ экипировал определенный лук или меч ?
 
Сверху Снизу