Тема: Изменение моделей офицеров, горожан и подобных персонажей.
Приветствую всех корсаров и пиратов! Сегодня я научу вас, как разнообразить внешний вид тех, кто готов помочь нам во время боя или тех, кто может встретиться с вами на суше в мирное время.
Сегодня нашим полем для деятельности будет являться файл “LAi_utilites.c”, располагается он в “PROGRAM\Loc_ai”, за наводку на этот файл спасибо Bab. Открываем этот файл, предварительно сохраните его копию куда-нибудь.
Часть первая: офицеры.
Важно: урок немного переписан, найдено лечение для бага с портретами в одну строку!
Ищем в нем такие строки:
// офицеры --> iCitizensQuantity = rand(6) - 3; for (i = 0; i { iChar = NPC_GeneratePhantomCharacter("pofficer", iNation, MAN, 1); chr = &characters[iChar]; SetNPCModelUniq(chr, "pofficer", MAN); SetOfficerParam(chr, rand(4)); sTemp = PlaceCharacter(chr, "sit", "random_free"); ReSitCharacterOnFree(chr, loc.id, sTemp); LAi_SetSitType(chr); // без группы chr.dialog.filename = "Enc_Officer_dialog.c"; chr.dialog.currentnode = "first time"; chr.greeting = "Gr_Officer";
И лишь одну строку, ту которую я выделил жирным превращаем в:
chr.model = LinkRandPhrase(Далее через запятую указываем модели под офицеров);
Обратите внимание: если вы добавляйте модели с одинаковым началом названия, но лишь с измененной на конце цифрой, то можете прописывать их так же, как я выше прописал модели оригинальных, не добавленных офицеров. В скобках должно быть число на 1 меньше, чем, то количество моделей, которое вы так прописали. У офицеров всего 20 моделей, значит, в скобках должно быть 19.
Теперь нужно добавить в код офицерам вот такую строку: "FaceMaker(chr);" я добавил ее над "SetOfficerParam(chr, rand(4));"
Новые офицеры появятся при старте новой игры.
Советую еще проверить по ресурсам игры, во всех ли папках с портретами есть портрет нужной модели НПС, а то я уже раз наткнулся на то, что файла с боевым портретом персонажа не было, а остальные были. Пути к портретам "\RESOURCE\Textures\BATTLE_INTERFACE\PORTRAITS" и "RESOURCE\Textures\INTERFACES\PORTRAITS". Боевой портрет может не отображаться из-за того, что он не прописан в “pictures.ini”, папка “\RESOURCE\INI\interfaces”. Пример (вместо 200 пишите номер портрета, остальное не трогаем):
Но и это еще не все. Думаете, снова кроем баг? Нет. Код, который ниже, позволит нам добавлять модели женщин и персонажей не с анимацией ГПК:
if (chr.model == "corsair1_3") // Название модели, в данном случае модель из ПКМ { chr.model.animation = "man2_ab"; // установили ему анимацию ПКМ chr.sex = "man"; // пол персонажа chr.FaceId = 201; // Номер портрета }
А вот этот код позволяет для каждой нации прописать своих офицеров. В примере условие лишь на пиратов, можете, если хотите прописать по аналогии модели для других наций, также в условии на нацию отсутствует “LinkRandPhrase”, но и ее можно использовать:
Выделяем весь этот кусок и удаляем его. Он нам больше не нужен. И вместо него вставляем (рядом с каждой строкой пишу, что за правка) :
// горожане --> arrayNPCModelHow = 0; // остаток первого метода if (checkAttribute(loc, "citizens")) //Снес проверку на тип локации, мешало работе метода { iCitizensQuantity = rand(8) + 6; // остаток первого метода for (i=1; i<=10; i++) // Все, что будет ниже в квадратных скобках, относится в данном случае к 10 людям. { chr = GetCharacter(NPC_GenerateCharacter("Gen_town_man_", "citiz_"+(rand(11)+1), "man", "man", sti(pchar.rank), iNation, 2, false)); // Следующие 2 строки создают НПС chr.id = "Gen_town_man_" + chr.index; chr.greeting = "cit_common"; // Тип звуковой фразы при начале диалога chr.CityType = "citizen"; // Тип в городе chr.reputation = (1 + rand(44) + rand(44)); // Случайный выбор репутации для НПС chr.City = Colonies[iColony].id; // Город chr.RebirthPhantom = true; // Следующие 4 строки отвечают за рост ранга НПС LAi_CharacterReincarnation(chr, true, true); LAi_SetReincarnationRankStep(chr, MOD_SKILL_ENEMY_RATE+2); SetFantomParamFromRank(chr, sti(pchar.rank)+MOD_SKILL_ENEMY_RATE, true); LAi_SetLoginTime(chr, 6.0, 22.0); // Время когда НПС есть в локации LAi_SetCitizenType(chr); // Тип, не путать с типом в городе, разные вещи PlaceCharacter(chr, "goto", "random_free"); // Группа и локатор НПС, в данном случае указан любой локатор группы goto chr.dialog.filename = "Common_citizen.c"; // Файл диалога chr.dialog.currentnode = "first time"; // Стартовый кейс диалога } for (i=1; i<=6; i++) // Теперь создадим особ прекрасного пола, в данном случае их 6, поясняю тут лишь уникальные для женщин строки кода { chr = GetCharacter(NPC_GenerateCharacter("Gen_town_woman_", "girl_"+(rand(8)+1), "woman", "towngirl", sti(pchar.rank), iNation, 2, false)); chr.id = "GenChar_woman" + chr.index; chr.greeting = "Gr_Woman_Citizen"; chr.CityType = "citizen"; chr.reputation = (1 + rand(44) + rand(44)); chr.City = Colonies[iColony].id; chr.dialog.filename = "Common_citizen.c"; chr.dialog.currentnode = "first time"; chr.RebirthPhantom = true; LAi_CharacterReincarnation(chr, true, true); LAi_SetReincarnationRankStep(chr, MOD_SKILL_ENEMY_RATE+2); SetFantomParamFromRank(chr, sti(pchar.rank)+MOD_SKILL_ENEMY_RATE, true); RemoveCharacterEquip(chr, BLADE_ITEM_TYPE); // Эти 2 строки забирают у женщин оружие RemoveCharacterEquip(chr, GUN_ITEM_TYPE); LAi_SetLoginTime(chr, 6.0, 22.0); LAi_SetCitizenType(chr); PlaceCharacter(chr, "goto", "random_free"); } } if (loc.type == "church") // Вынес проверку на церковь отдельно { makearef(st, loc.locators.sit); iCitizensQuantity = rand(6) + 2; for (i=0; i { iChar = NPC_GeneratePhantomCharacter("citizen", iNation, MAN, 1); //Генерируем фантома chr = &characters[iChar]; chr.model = "citiz_"+(rand(11)+1); // модель LAi_SetSitType(chr); // Сидит chr.nonTable = true; // Не за столом PlaceCharacter(chr, "sit", "random_free"); chr.dialog.filename = "Enc_Walker.c"; chr.dialog.currentnode = "first time"; SetFantomParamFromRank(chr, sti(pchar.rank), true); } } // горожане <--
На этом все!
Часть третья: фантомы резиденции.
Все-таки не могу я отказать коллеге по работе с программной частью ГПК в помощи, тем более, если вопрос интересен и мне самому. Сегодня Vaga спрашивал про количество слуг и солдат в резиденции. Даю развернутый ответ, что да как.
Количество солдат в резиденции равно количеству локаторов группы “patrol”. Больше таких локаторов - больше солдат. А вот со слугами работы чуть больше, но лишь программно: открываем мой любимый файл “LAi_utilites.c”, располагается он в “PROGRAM\Loc_ai”, и ищем:
void CreateInsideResidenceEncounters(aref loc) { if (CheckAttribute(loc, "MustSetReloadBack")) { //если заглушка if (loc.id.label == "TownhallRoom" || loc.id.label == "Townhall") // Добавил проверку на лейбл локации { CreateResidenceNpc(loc); } } else { //если статичная локация if (loc.id.label == "TownhallRoom" || loc.id.label == "Townhall") { CreateResidenceNpc(loc); } } } //относится к методу выше void CreateResidenceNpc(aref loc) { ref chr; int Rank; string sModel, sSex, sAni, sNode, sGreeting; bool bWeapon; int iBaseCity = FindLocation(loc.fastreload + "_town"); if (!CheckAttribute(&locations[iBaseCity], "houseEnc")) return; //if (rand(10) > 8) return; //шанс на пустую комнату, если нужны всегда, то удаляйте эту строку //==> выбираем тип int iEncType = rand(2); //0 - служанка, 1 - прислуга, 2 - солдат. if (loc.id.label == "TownhallRoom") iEncType = 2; if (CheckAttribute(loc, "Bedroom") || loc.id.label == "Townhall") iEncType = 0; // Добавил проверку на лейбл локации if (CheckAttribute(loc, "PlayHall") || loc.id.label == "Townhall") iEncType = 1; // Добавил проверку на лейбл локации int iNation = GetCityNation(loc.fastreload); if (iNation == PIRATE) return; //пиратские резиденции нам не нужны switch (iEncType) { case 0: Rank = 3; sModel = "girl_"+(rand(9)+1); sSex = "woman"; sAni = "towngirl" bWeapon = false; sNode = "ResWoman"; sGreeting = "Gr_Woman_Citizen"; break; case 1: Rank = 5; sModel = "barmen_"+(rand(15)+1); sSex = "man"; sAni = "man" bWeapon = true; sNode = "ResMan"; sGreeting = "worker"; break; case 2: Rank = sti(pchar.rank) + MOD_SKILL_ENEMY_RATE; sModel = "sold_"+NationShortName(iNation)+"_"+(rand(7)+1); sSex = "man"; sAni = "man" bWeapon = true; sNode = "ResGuard"; sGreeting = "guardHouse"; break; } //==> генерим непися string slai_group = GetNationNameByType(iNation) + "_citizens"; string sName = "EncResidence_" + iBaseCity + "_" + loc.index; if (GetCharacterIndex(sName) > 0) return; //если есть chr = GetCharacter(NPC_GenerateCharacter(sName, sModel, sSex, sAni, Rank, iNation, 1, bWeapon)); chr.dialog.Filename = "ResidenceEnc_dialog.c"; chr.dialog.currentnode = sNode; chr.CityType = "citizen"; chr.city = loc.fastreload; //НЗГ chr.greeting = sGreeting; if(loc.id.label == "Townhall") // Добавил проверку на лейбл локации, если оно выполняется, то персонаж стоит в одном месте, если нет, то в другом. { ChangeCharacterAddressGroup(chr, loc.id, "goto", "goto1"); } else { ChangeCharacterAddressGroup(chr, loc.id, "barmen", "stay"); } LAi_SetOwnerType(chr); LAi_group_MoveCharacter(chr, slai_group); }
С этим файлом все. Далее во всех файлах, где прописаны локации-резиденции (путь к ним: “PROGRAM\locations\init”) нужно добавить строку “locations[n].MustSetReloadBack = true;” над разделом “//Town sack”:
Затем сохранить изменения и начать игру заново! Все!
Небольшой FAQ по правкам (сюда буду писать ответы на частые вопросы):
Часть первая: офицеры:
В: Как сделать, чтобы офицеры, следовали за ГГ в те, локации, куда они обычно не ходят за ним? Например, церкви.
О: Во всех таких локациях отсутствуют нужные для офицеров, группа локаторов "officers". Если включить локаторы, то заметите, что у каждого локатора группы "reload" есть 3 локатора группы "officers". И что бы офицеры следовали за ГГ нужно добавить эти локаторы через TOOL.
Вторая часть: горожане:
В: Вставил данный код: на Бермудах исчезли пираты, но есть обычные горожане, с пиратскими диалогами.
О: Пираты – охранники нуждаются в локаторах группы “patrol”, создайте парочку через TOOL. Решение снести пиратов было принято мной после изучения файла, который мы сейчас правили. Пираты - патрульные уже есть в нем, но из-за отсутствия нужной группы локаторов их нет на Бермудах. На счет диалогов: в файле “Common_citizen.c”:
if (sti(NPChar.nation) == PIRATE) { if (sti(rColony.HeroOwn) == true) // наш горожанин { dialog.text = RandPhraseSimple("Ходит слух, что вы и есть владелец этого города, сэр.", "Какая приятная встреча, сам глава города обратился ко мне с вопросом."); link.l1 = RandPhraseSimple("Я передумал. Удачи!", "Просто осматриваю город. До свидания."); link.l1.go = "exit"; link.l2 = RandPhraseSimple("У меня есть вопрос к тебе.", "Мне нужна информация."); link.l2.go = "quests";//(перессылка в файл города) if (CheckAttribute(pchar, "GenQuest.Loan.FindCitizen") && !CheckAttribute(pchar, "GenQuest.Loan.FindCitizenDone") && !CheckAttribute(pchar, "GenQuest.Loan.FindCitizenFalied")) { if (Characters[sti(pchar.GenQuest.Loan.FindCitizenIdx)].id == Npchar.id) { link.l3 = RandPhraseSimple("Хочу обсудить финансовые дела.", "Касательно финансов..."); link.l3.go = "LoanForAll";//(перессылка в кредитный генератор) } } break; } else { // пираты, не наши dialog.text = RandPhraseSimple("Чего тебе? Проходи мимо.", "Хватит загораживать дорогу, отвали."); link.l1 = RandPhraseSimple("Уже ушел.", "Не нужно мне грубить. До свидания."); link.l1.go = "exit"; link.l2 = RandPhraseSimple("Всего один маленький вопросик.", "Минутку внимания, всего один небольшой вопрос."); link.l2.go = "quests";//(перессылка в файл города) if (CheckAttribute(pchar, "GenQuest.Loan.FindCitizen") && !CheckAttribute(pchar, "GenQuest.Loan.FindCitizenDone") && !CheckAttribute(pchar, "GenQuest.Loan.FindCitizenFalied")) { if (Characters[sti(pchar.GenQuest.Loan.FindCitizenIdx)].id == Npchar.id) { link.l3 = RandPhraseSimple("Хочу обсудить финансовые дела.", "Касательно финансов..."); link.l3.go = "LoanForAll";//(перессылка в кредитный генератор) } } break; } }
Заменить на:
if (sti(rColony.HeroOwn) == true) // наш горожанин { dialog.text = RandPhraseSimple("Ходит слух, что вы и есть владелец этого города, сэр.", "Какая приятная встреча, сам глава города обратился ко мне с вопросом."); link.l1 = RandPhraseSimple("Я передумал. Удачи!", "Просто осматриваю город. До свидания."); link.l1.go = "exit"; link.l2 = RandPhraseSimple("У меня есть вопрос к тебе.", "Мне нужна информация."); link.l2.go = "quests";//(перессылка в файл города) if (CheckAttribute(pchar, "GenQuest.Loan.FindCitizen") && !CheckAttribute(pchar, "GenQuest.Loan.FindCitizenDone") && !CheckAttribute(pchar, "GenQuest.Loan.FindCitizenFalied")) { if (Characters[sti(pchar.GenQuest.Loan.FindCitizenIdx)].id == Npchar.id) { link.l3 = RandPhraseSimple("Хочу обсудить финансовые дела.", "Касательно финансов..."); link.l3.go = "LoanForAll";//(перессылка в кредитный генератор) } } break;
Дата создания урока: Первая часть: 01.12.2011 г. Вторая часть: 15.01.2012 г. Третья часть: 06.03.2012г. Пополнение FAQ: 07.03.2012г. Myth: Make Your Thought Heard
Сообщение отредактировал Myth - Среда, 07.03.2012, 18:42
получилось, тока с портретами... на каждого офа по разному, как будто рандом на портреты, ща буду разбираться
Добавлено (28.12.2011, 19:04) --------------------------------------------- я имел в виду, если в другой таверне попадаеться такаяже модель офа, то портрет другой уже, или сидят два разных офа, а портрет одинаковый у обоих
Добавлено (28.12.2011, 19:06) --------------------------------------------- слушай "man3" это у тебя модель или ссылка на анимацию?
Добавлено (28.12.2011, 19:14) --------------------------------------------- ))) по поводу портретов извеняюсь не до конца прочел, ща исправим.
атлична как с офами закончу займусь этим. Идея по разным нациям офоф понравилась. буду оригинальным моделям лица перерисовывать и шмот.Процес правда долгий и не простой, но внесет разноообразия побольше в игру.
ну если ты дружишь с фотошопом... после нового года я подумаю над этим проэктом. Ну а так помощь может понадобиться с поиском материала по текстурам в сети по шмоту тех времен. я вразумительного и четкого изо так и не нашел.
Добавлено (28.12.2011, 21:10) --------------------------------------------- с лицами посложней придеться, вазможно с нуля придеться рисовать, а проще подогнать, подтянуть и растянуть готовые))
Добавлено (28.12.2011, 21:40) --------------------------------------------- найти бы кто умеет 3D модели править. я бы забабахал блада таким каким он был в фильме. Я уже фейз его подставил одной модели, отдаленно напоминает, тока-бы этой модели волос подлиней и лоб повыше. Но чет я ужо от темы отклонился, звеняюсь за это
Добавлено (29.12.2011, 00:40) --------------------------------------------- С горожанами не сработало. Игра перестает запускаться.
Джин-Бейн, ну ка покажи как ты их правил... На счет моделей я бы тоже с ними поработал. Слышал, что как то в модели ПКМ вставляют новый скелет от ГПК и модель работает с стандартной анимацией. У моделей из ПКМ есть небольшие глюки анимации в сидячем положении в ГПК. Хотел бы их поправить. Myth: Make Your Thought Heard
Сообщение отредактировал Myth - Четверг, 29.12.2011, 10:18
Как править скелет я не знаю, но дагадываюсь. Скорее всего через Майку пятую, у меня она не хочет запускаться, а то-бы я с 3D модклями с удовольствием позанимался.
Джин-Бейн, если майка у тебя ключик просит могу дать инструкцию в ЛС. Это я тоже проходил. На счет горожан снова та жа ошибка chr.model = "citizen"+(rand(13)+1); LinkRandPhrase нужна если идут модели с разными названиями. Myth: Make Your Thought Heard
Насчет майки буду рад получить помощь, но передупреждаю колдовать с кряком на нее я уже пробовал, но все равно мож у тья новый способ, так что давай инструкцию. по поводу горожан, тогда как верно? ты меня совсем запутал, с офицерами ведь прокатило, там ведь модели у меня с одинаковыми названиями "officer_19.gm", "officer_20.gm", "officer_21.gm", officer_22.gm". И с горожанами, я назвал их по такомуже принципу, т.е. "citiz_12.gm", "citiz_13.gm" и т.д