09:16
ОбновитьСмайлыУправление мини-чатом
Мини чат

[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Модератор форума: Rasteador, Королёв  
Форум » Любительские модификации для "Корсаров" » Уроки по созданию модификаций » Урок: Пишем квест (сухопутный) и создаем файл для него
Урок: Пишем квест (сухопутный) и создаем файл для него
ChernozmeyДата: Понедельник, 25.11.2013, 11:45 | Сообщение # 1
 Капитан-лейтенант
Сообщений:
343
Награды:
Репутация:
Замечания:
Урок: Пишем квест (сухопутный) и создаем файл для него.


Напишем вначале сухопутный квест, научимся управлять НПС и ГГ, а потом уже и в море отправимся. Для начала создадим собственный файл для квестов и интегрируем его в игру. Создадим в любом текстовом редакторе файл и сохраним его под именем My_quests.c (путь program\quests). Назвать можно совершенно по любому.

Пропишем в него следующий код:

Код
void MyQuestComplete(string sQuestName, string qname)
{
ref chr, PChar, sld;
PChar = GetMainCharacter();
switch(sQuestName)
{
              // здесь будем вставлять case квестов
}   
}

Это обязательная кодировка файла.
void MyQuestComplete(string sQuestName, string qname) – My, можно заменить на собственное название.

Служебная часть может иметь и другой вид, все зависит от того, сколько переменных и т.д. вы описыаете:

Код
ref chr, pirate, PChar, sld, man, rFamousCharacter, DyingCharacter, rPirateToShoreCaptivityQuest;
PChar = GetMainCharacter();
string homelocation, homegroup, homelocator, tavernfriend, sLocator, sFortCommander, sExColony;   
int iCompanionedNation, iPassenger, iHouseBanditMoney, iColony, iTradeGoods, iQuantityGoods, iTradeNation, MoneyForHouse, iTeacherTime;
int iTradeColony, iOfficer, iExColony, iExNation, iPRM, idLngFile, iTreasuresSneak, iGenSYQuestPatrolChance;
int iGenSYQuestPatrolNation, HouseQuestPatrolChance;
iTreasuresSneak = GetCharacterSkill(PChar, SKILL_SNEAK);
float locx, locy, locz;


Далее, интегрируем файл в игру. Для этого открываем файл quests.с (путь program\quests), находим в нем строку, #include "quests\quests_reaction.c", копируем ее и вставляем имя своего файла, чтобы получилось
Код
#include "quests\ My_quests.c"

В том же файле ищем строку
Код
void CompleteQuestName(string sQuestName, string qname)

под ней находим QuestComplete(sQuestName, qname);, копируем и изменяем так, чтобы получилось следующее
Код
MyQuestComplete(sQuestName, qname);


Далее открываем файл quests_check.с (путь program\quests), и находим так такую строку
Код
void OnQuestComplete(aref quest, string sQuestname)

под ней находим QuestComplete(quest.win_condition, sQuestName);, копируем и изменяем так, чтобы получилось
Код
MyQuestComplete(quest.win_condition, sQuestName);

Теперь ищем строку
Код
void OnQuestFailed(aref quest, string sQuestName)

под ней находим QuestComplete(quest.fail_condition, sQuestName);, копируем и изменяем так, чтобы получилось
Код
MyQuestComplete(quest.fail_condition, sQuestName);


Далее открываем файл utils.с (путь program\battle_interface). Находим там строку
Код
void procTimerTimeOut()

под ней находим QuestComplete(objTimerInterface.questtype, objTimerInterface.questname);, копируем и изменяем так, чтобы получилось
Код
MyComplete(objTimerInterface.questtype, objTimerInterface.questname);

Все, теперь наш файл My_quests.c интегрирован в игру и можно спокойно писать в нем квесты.

Начнем. Для начала придумаем нехитрый сюжет (возьму из своего квеста к КТДМ): ГГ встречает священника и тот просит найти и помочь девушке за вознаграждение. ГГ находит девушку и во время разговора к нем приходит враждебный НПС, они разговаривают, (кстати будет показано как писать диалог на троих) а потом происходит дуэль между ГГ и НПС. Потом ГГ возвращается к священнику и получает награду.

Самое первое, это создание персонажей, НПС то есть. Вот этим и займемся. Значит, у нас есть священник, в одной локации, девушка в другой локации, а потом еще один НПС прибудет в ту же локацию, что и девушка. Вначале, выберем модельки НПС для нашей истории с помощью программы GM Viewer и прописываем код нашим НПС. (Так как уже существуют уроки по написании НПС и диалогов, объяснять тут, что к чему, уже не буду). Скажу только то, что священника мы сразу помещаем в локацию, остальные НПС возникнут в локациях по мере прохождения квеста, то есть исполнения case квеста. Некоторые выражения, использованные в этом уроке, вообще не нужны для исполнения данного квеста, просто привел их как дополнения, чтобы не описывать отдельно.

Код
makeref(ch,Characters[n]);    // священник    
ch.id = "First Church Treas";
ch.name = "Вито";
ch.lastname = "Корелиус";
ch.model = "priest_2";
ch.location    = "SanSebastian_door58";   
ch.location.group = "goto";
ch.location.locator = "goto1";
ch.Dialog.Filename = "CH_Kornelius_dialog.c";
ch.namelock = 1;   
ch.QuestLock = 1;   
ch.sex = "man";
LAi_SetImmortal(ch, true);
Lai_SetStayType(ch);
n = n + 1;

makeref(ch,Characters[n]);    // жених   
ch.id = "Geneshok";
ch.name = "жених";
ch.lastname = "Кончиты";
ch.rank = 5;
ch.model = "pirate_9";
ch.nation = PIRATE;
ch.Dialog.Filename = "CH_Genish_dialog.c";
ch.RemoveLock = true;   
ch.skill.Fencing = "5";
ch.skill.Gun = "5";   
ch.sex = "man";
ch.CanThiefed = "false";
LAi_NPC_Equip(ch, ch.rank, true, true);   
LAi_SetImmortal(ch, true);
Lai_SetStayType(ch);
n = n + 1;   
      
makeref(ch,Characters[n]);  // Кончита
ch.id = "Konchitas";
ch.name = "Кончита";
ch.lastname = "";
ch.model = "lady_6";   
ch.RemoveLock = true;   
ch.Dialog.Filename = "CH_Konchitas_dialog.c";
ch.namelock = 1;
ch.QuestLock = 1;
ch.sex = "woman";
ch.CanThiefed = "false";
LAi_SetImmortal(ch, true);
Lai_SetStayType(ch);
n = n + 1;


Далее пишем диалоги для всех НПС.

CH_Kornelius_dialog.с
Код
case "First time":
dialog.text = "А-а-а... Вот и вы, молодой человек.";
link.l1 = "(удивленно) Вы меня знаете?";
link.l1.go = "corn_deal_1";
break;
case "corn_deal_1":
dialog.text = "Нет... А вы разве не молодой человек? Я уже стар и может глаза подводят меня...";
link.l1 = "Нет, нет. Я молод...";
link.l1.go = "corn_deal_2";
break;
case "corn_deal_2":
dialog.text = "А-а-а, понятно. Вы, наверное, давно не были у лекаря. Ну да ладно, хотите получить 20 000 золотых и спасти красивенькую женщину?";
link.l1 = "Неожиданно... Хотя, не откажусь, деньги то немалые. Вот только пункт со спасением меня смущает. Это не очень опасно?";
link.l1.go = "corn_deal_4";
break;
case "corn_deal_4":
dialog.text = "Такой храбрый капитан и вдруг такие речи. Видимо, каждому свое.";
link.l1 = "Классная игра, кстати. Ближе к делу ваше святейшество.";
link.l1.go = "corn_deal_5";
break;
case "corn_deal_5":
dialog.text = "Вот, вот. Правильные слова. Чтобы получить деньги, надо спасти девушку (замолкает).";
link.l1 = "Иииии...";
link.l1.go = "corn_deal_6";
break;
case "corn_deal_6":
dialog.text = "И все, капитан.";
link.l1 = "То есть, как это все?";
link.l1.go = "corn_deal_7";
break;
case "corn_deal_7":
dialog.text = "Для вас капитан, повторю отдельно. Надо, спасти девушку и тогда, и только тогда... не раньше... но и не позже, вы получите деньги.";
link.l1 = "Это-то я понял...";
link.l1.go = "corn_deal_8";
break;
case "corn_deal_8":
dialog.text = "Странно, но пусть так оно и будет. Стесняюсь спросить, а что именно вам не понятно?";
link.l1 = "Где искать девушку?";
link.l1.go = "corn_deal_9";
break;
case "corn_deal_9":
dialog.text = "Ах, вот оно что. Точно сказать не могу, но она где-то в городе. Учитывая, что девушка любит морские виды, то я бы поискал ее около моря.";
link.l1 = "Я все понял.";
link.l1.go = "corn_deal_10";
break;
case "corn_deal_10":
dialog.text = "Рад за вас.";
link.l1 = "Вскоре я вернусь, отче. Не уходите далеко.";
link.l1.go = "corn_deal_11";
break;
case "corn_deal_11":
dialog.text = "И если вам это интересно, то девушку зовут Кончита. Надеюсь, это облегчит ваши поиски.";
link.l1 = "Да-да... я скоро.";
link.l1.go = "corn_deal_12";
break;
case "corn_deal_a12":
dialog.text = "Ну... как ваши дела?";
link.l1 = "Отлично. Кончита свободна. Я только что убил ее жениха.";
link.l1.go = "corn_deal_a13";
break;
case "corn_deal_a13":
dialog.text = "А вы не промах, капитан.";
link.l1 = "Теперь, мне осталось получить свое вознаграждение.";
link.l1.go = "corn_deal_a14";
break;
case "corn_deal_a14":
dialog.text = "Ах, да. Вот ваши 20 000, золотом. Но, уверен, вы не успеете их потратить.";
link.l1 = "...";
link.l1.go = "corn_deal_a15";
break;
case "Second time":
dialog.text = "Ой, мужчина. А вы кто?";
link.l1 = "Священник сбрендил";
link.l1.go = "exit";
break;   
case "exit":
NextDiag.TempNode = "Second time";
NextDiag.CurrentNode = NextDiag.TempNode;
DialogExit();
break;    
case "corn_deal_12":
AddDialogExitQuest("ChurchTreasure_1");
NextDiag.TempNode = "Second time";
NextDiag.CurrentNode = NextDiag.TempNode;
DialogExit();
break;
case "corn_deal_a15":
AddMoneyToCharacter(pchar, +20000);
AddDialogExitQuest("ChurchTreasure_20");
ChangeCharacterAddress(characterFromID("First Church Treas"), "None", "");
NextDiag.CurrentNode = NextDiag.TempNode;
DialogExit();
break;


Примечание: ChangeCharacterAddress(characterFromID("id НПС"), "None", ""); - убирает НПС из локации.

CH_Konchitas_dialog.с
Код
case "First time":
dialog.text = "Что привело вас в мой дом?";
link.l1 = "Это вы?";
link.l1.go = "devushka_deal_1";
break;
case "devushka_deal_1":
dialog.text = "Наверное... Смотря кто вам нужен.";
link.l1 = "Мне нужна девушка.";
link.l1.go = "devushka_deal_2";
break;
case "devushka_deal_2":
dialog.text = "Увы, мой дорогой, но тут ничем вам помочь не могу.";
link.l1 = "Как так?";
link.l1.go = "devushka_deal_4";
break;
case "devushka_deal_4":
dialog.text = "(странно смотрит) Вы давно не обращались к лекарю?";
link.l1 = "Меня уже сегодня спрашивали об этом.";
link.l1.go = "devushka_deal_5";
break;
case "devushka_deal_5":
dialog.text = "Поздравляю. А теперь перейдем к сути вашей проблемки. Как я понимаю, вам нужна девушка, но девушек тут нет. В этом доме только я и я не...";
link.l1 = "Мне нужна не девушка...";
link.l1.go = "devushka_deal_6";
break;
case "devushka_deal_6":
dialog.text = "Ну и ну.";
link.l1 = "Мне нужна Кончита...";
link.l1.go = "devushka_deal_7";
break;
case "devushka_deal_7":
dialog.text = "Откуда вам известно это имя?";
link.l1 = "Мне его назвал священник...";
link.l1.go = "devushka_deal_8";
break;
case "devushka_deal_8":
dialog.text = "Вито Корнелиус?";
link.l1 = "У меня плохая память на имена.";
link.l1.go = "devushka_deal_9";
break;
case "devushka_deal_9":
dialog.text = "Да не важно. И что там священник..?";
link.l1 = "А-а-а-а... Он просил спасти девушку Кончиту...";
link.l1.go = "devushka_deal_10";
break;
case "devushka_deal_10":
dialog.text = "(стук в дверь) Кто там?";
link.l1 = "Кто-то пришел.";
link.l1.go = "devushka_deal_11";
break;
case "devushka_deal_11c":
dialog.text = "Кто?";
link.l1 = "...";
link.l1.go = "devushka_deal_11b";
break;
case "devushka_deal_12":
dialog.text = "Этот парень?";
link.l1 = "...";
link.l1.go = "devushka_deal_12b";
break;
case "devushka_deal_13":
dialog.text = "Это парень.";
link.l1 = "...";
link.l1.go = "devushka_deal_13b";
break;
case "devushka_deal_14":
dialog.text = "Ах, мне дурно...";
link.l1 = "...";
link.l1.go = "devushka_deal_14a";
break;
case "Second time":
dialog.text = "Парниша... не желаешь познакомиться?";
link.l1 = "Виделись уже.";
link.l1.go = "exit";
break;   
case "exit":
NextDiag.TempNode = "Second time";
NextDiag.CurrentNode = NextDiag.TempNode;
DialogExit();
break;    
case "devushka_deal_11":
AddDialogExitQuest("ChurchTreasure_3");
NextDiag.CurrentNode = NextDiag.TempNode;
DialogExit();
break;
case "devushka_deal_11b":
AddDialogExitQuest("ChurchTreasure_6");
NextDiag.CurrentNode = NextDiag.TempNode;
DialogExit();
break;
case "devushka_deal_12b":
AddDialogExitQuest("ChurchTreasure_8");
NextDiag.CurrentNode = NextDiag.TempNode;
DialogExit();
break;
case "devushka_deal_13b":
AddDialogExitQuest("ChurchTreasure_10");
NextDiag.CurrentNode = NextDiag.TempNode;
DialogExit();
break;
case "devushka_deal_14a":
AddDialogExitQuest("ChurchTreasure_12");
NextDiag.CurrentNode = NextDiag.TempNode;
DialogExit();
break;


CH_Genish_dialog.c
Код
case "First time":
dialog.text = "Это кто?";
link.l1 = "...";
link.l1.go = "manna_deal_1";
break;
case "manna_deal_2":
dialog.text = "Вот он… кто?";
link.l1 = "...";
link.l1.go = "manna_deal_2a";
break;
case "manna_deal_3":
dialog.text = "Ага... он... кто,  спрашиваю?";
link.l1 = "...";
link.l1.go = "manna_deal_3a";
break;
case "manna_deal_4":
dialog.text = "Не слепой, вижу. Так кто же он?";
link.l1 = "Сеньор, вас заклинило? Вы спрашиваете все время об одном и том же. Вам не дурно? Может позвать лекаря?";
link.l1.go = "manna_deal_5";
break;
case "manna_deal_5":
dialog.text = "Ты кто?";
link.l1 = "Я парень...";
link.l1.go = "manna_deal_6";
break;
case "manna_deal_6":
dialog.text = "Да неужели? И что тебе нужно в этом доме?";
link.l1 = "Мне поручили найти девушку Кончиту...";
link.l1.go = "manna_deal_7";
break;
case "manna_deal_7":
dialog.text = "А вот это уже интересно.";
link.l1 = "Но, вот эта сеньора сказала, что девушки Кончиты здесь нет.";
link.l1.go = "manna_deal_8";
break;
case "manna_deal_8":
dialog.text = "Становиться еще интереснее. А кто тогда здесь есть?";
link.l1 = "Эта сеньора сказала, что здесь есть только она… а девушки здесь нет. И как мне думается, Кончиты здесь тоже нет...";
link.l1.go = "manna_deal_9";
break;
case "manna_deal_9":
dialog.text = "А вот тут ты не прав. Эта сеньора, которая уже не девушка, и есть Кончита. Правда, я думал, что она еще девушка, моя-то невестушка... Но, каждый волен ошибиться.";
link.l1 = "...";
link.l1.go = "manna_deal_9a";
break;
case "manna_deal_10":
dialog.text = "Будет еще дурнее, когда я тебя батогами отхожу.";
link.l1 = "Сеньор, вы хам...";
link.l1.go = "manna_deal_11";
break;
case "manna_deal_11":
dialog.text = "А ты вообще заткнись.";
link.l1 = "Вот такого я не спущу. (слышится звон пощечины) Вызываю вас на дуэль.";
link.l1.go = "manna_deal_12";
break;
case "manna_deal_12":
dialog.text = "Я тебе сейчас уши обрежу, молокосос.";
link.l1 = "Уже побежал.";
link.l1.go = "manna_deal_13";
break;
case "manna_deal_15a":
dialog.text = "Вытаскивай свою железку. Сейчас ты будешь умирать...";
link.l1 = "К бою...";
link.l1.go = "manna_deal_16a";
break;
case "Second time":
dialog.text = "А вы кто?";
link.l1 = "..?";
link.l1.go = "exit";
break;   
case "exit":
NextDiag.TempNode = "Second time";
NextDiag.CurrentNode = NextDiag.TempNode;
DialogExit();
break;    
case "manna_deal_1":
AddDialogExitQuest("ChurchTreasure_5");
NextDiag.CurrentNode = NextDiag.TempNode;
DialogExit();
break;
case "manna_deal_2a":
AddDialogExitQuest("ChurchTreasure_7");
NextDiag.CurrentNode = NextDiag.TempNode;
DialogExit();
break;
case "manna_deal_3a":
AddDialogExitQuest("ChurchTreasure_9");
NextDiag.CurrentNode = NextDiag.TempNode;
DialogExit();
break;
case "manna_deal_9a":
AddDialogExitQuest("ChurchTreasure_11");
NextDiag.CurrentNode = NextDiag.TempNode;
DialogExit();
break;
case "manna_deal_13":
AddDialogExitQuest("ChurchTreasure_13");
NextDiag.CurrentNode = NextDiag.TempNode;
DialogExit();
break;
case "manna_deal_16a":
AddDialogExitQuest("ChurchTreasure_15");
NextDiag.CurrentNode = NextDiag.TempNode;
DialogExit();
break;


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

Код
case "ChurchTreasure":
pchar.quest.ChurchTreasure0.win_condition.l1 = "location";
pchar.quest.ChurchTreasure0.win_condition.l1.location = "SanSebastian_door58";
pchar.quest.ChurchTreasure0.win_condition = "ChurchTreasure0";
break;


case "ChurchTreasure": - case квеста и название case
pchar.quest.ChurchTreasure0.win_condition.l1 = "location"; - условие, нахождение в локации
pchar.quest.ChurchTreasure0.win_condition.l1.location = "SanSebastian_door58"; - id локации
pchar.quest.ChurchTreasure0.win_condition = "ChurchTreasure0"; - имя case который будет запущен.

Примечание: pchar.quest.(QuestName).win_condition.l1 = "условие выполнения"; - условия выполнения case для запуска последующего case квеста. Они могут быть различными. В конце урока есть дополнение, где приведены различные win_condition с объяснениями, для чего они нужны.

Код
case "ChurchTreasure0":
Lai_setActorType(Pchar);
LAi_ActorFollow(Pchar, CharacterFromID("First Church Treas"), "", -1);   
Lai_setActorType(CharacterFromID("First Church Treas"));
LAi_ActorFollow(CharacterFromID("First Church Treas"), Pchar, "ChurchTreasure0a", -1);   
break;


Lai_setActorType(Pchar); - поменять тип ГГ на актера, отменяет управление
LAi_ActorFollow(Pchar, CharacterFromID("First Church Treas"), "", -1); - ГГ идет в сторону НПС, в нашем случае, к священнику
Lai_setActorType(CharacterFromID("First Church Treas")); - НПС присваивается тип «актер»
LAi_ActorFollow(CharacterFromID("First Church Treas"), Pchar, "ChurchTreasure0a", -1); - НПС идет к ГГ

Примечание: все доступные функции описаны в файле functions.txt (путь program\loc_ai\doc )

Код
case "ChurchTreasure0a":
Lai_setPlayerType(Pchar);
LAi_SetActorType(characterFromID("First Church Treas"));
Characters[GetCharacterIndex("First Church Treas")].Dialog.CurrentNode = "First time";   
Lai_ActorDialogNow(characterFromID("First Church Treas"), Pchar, "",-1);
break;


Lai_setPlayerType(Pchar); - дает ГГ тип «игрока», то есть, есть возможность управлять ГГ в игре
Lai_ActorDialogNow(characterFromID("First Church Treas"), Pchar, "",-1); - начать диалог между НПС и ГГ

продолжение будет скоро


 
АгниДата: Понедельник, 25.11.2013, 11:56 | Сообщение # 2
 Друг муравьев и меда 
 Адмирал
Сообщений:
762
Награды:
Репутация:
Больше пиастров в квестах! biggrin

 
ChernozmeyДата: Понедельник, 25.11.2013, 12:04 | Сообщение # 3
 Капитан-лейтенант
Сообщений:
343
Награды:
Репутация:
Замечания:
продолжение


Код
case "ChurchTreasure_1":
SetQuestHeader("ChurchTrs");
AddQuestRecord("ChurchTrs", "1");  
Lai_setPlayerType(characterFromID("First Church Treas"));
Lai_setCitizenType(characterFromID("First Church Treas"));
ChangeCharacterAddressGroup(CharacterFromID("Konchitas"), "SanSeb_port_door_4", "goto", "goto2");  
PChar.quest.ChurchTreasure_2.win_condition.l1 = "location";  
PChar.quest.ChurchTreasure_2.win_condition.l1.location = "SanSeb_port_door_4";
PChar.quest.ChurchTreasure_2.win_condition = "ChurchTreasure_2";
break;


SetQuestHeader("ChurchTrs"); - открывает тему квеста в СЖ
AddQuestRecord("ChurchTrs", "1"); - добавляет запись в СЖ под номером 1
Lai_setPlayerType(characterFromID("First Church Treas")); - делает НПС игроком
Lai_setCitizenType(characterFromID("First Church Treas")); - делает НПС горожанином, то есть, НПС ходит туда-сюда
ChangeCharacterAddressGroup(CharacterFromID("Konchitas"), "SanSeb_port_door_4", "goto", "goto2"); - добавляет в игру НПС, в нашем случае, НПС Кончита появляется в локации SanSeb_port_door_4, имеет отношение к группе локаторов goto и стоит точно в локаторе goto2

Код
case "ChurchTreasure_2":
Locations[FindLocation("SanSeb_port_door_4")].reload.l1.disable = true;
Lai_setActorType(Pchar);
LAi_ActorFollow(Pchar, CharacterFromID("Konchitas"), "", -1);  
Lai_setActorType(CharacterFromID("Konchitas"));
LAi_ActorFollow(CharacterFromID("Konchitas"), Pchar, "ChurchTreasure_2a", -1);
break;


Locations[FindLocation("SanSeb_port_door_4")].reload.l1.disable = true; - закрывает локацию, что бы ГГ не смог выйти из нее.

Код
case "ChurchTreasure_2a":
Lai_setPlayerType(Pchar);
LAi_SetActorType(characterFromID("Konchitas"));
Characters[GetCharacterIndex("Konchitas")].Dialog.CurrentNode = "First time";  
Lai_ActorDialogNow(characterFromID("Konchitas"), Pchar, "",-1);
break;
    
case "ChurchTreasure_3":
DoQuestCheckDelay("ChurchTreasure_4", 0.1);
break;


DoQuestCheckDelay("ChurchTreasure_4", 0.1); - задержка исполнения case квеста на время 0.1 в секундах

Код
case "ChurchTreasure_4":
ChangeCharacterAddressGroup(CharacterFromID("Geneshok"), "SanSeb_port_door_4", "goto", "goto3");  
Lai_setActorType(CharacterFromID("Geneshok"));
LAi_ActorFollow(CharacterFromID("Geneshok"), Pchar, "ChurchTreasure_4a", -1);
break;


Отсюда начинается диалог на троих. Можно посмотреть взаимосвязь case диалогов и case квестов.

Код
case "ChurchTreasure_4a":
LAi_SetActorType(characterFromID("Geneshok"));
Characters[GetCharacterIndex("Geneshok")].Dialog.CurrentNode = "First time";  
Lai_ActorDialogNow(characterFromID("Geneshok"), Pchar, "",-1);
break;
    
case "ChurchTreasure_5":
LAi_SetActorType(characterFromID("Konchitas"));
Characters[GetCharacterIndex("Konchitas")].Dialog.CurrentNode = "devushka_deal_11c";  
Lai_ActorDialogNow(characterFromID("Konchitas"), Pchar, "",-1);
break;
    
case "ChurchTreasure_6":
LAi_SetActorType(characterFromID("Geneshok"));
Characters[GetCharacterIndex("Geneshok")].Dialog.CurrentNode = "manna_deal_2";  
Lai_ActorDialogNow(characterFromID("Geneshok"), Pchar, "",-1);
break;
    
case "ChurchTreasure_7":
LAi_SetActorType(characterFromID("Konchitas"));
Characters[GetCharacterIndex("Konchitas")].Dialog.CurrentNode = "devushka_deal_12";  
Lai_ActorDialogNow(characterFromID("Konchitas"), Pchar, "",-1);
break;
    
case "ChurchTreasure_8":
LAi_SetActorType(characterFromID("Geneshok"));
Characters[GetCharacterIndex("Geneshok")].Dialog.CurrentNode = "manna_deal_3";  
Lai_ActorDialogNow(characterFromID("Geneshok"), Pchar, "",-1);
break;
   
case "ChurchTreasure_9":
LAi_SetActorType(characterFromID("Konchitas"));
Characters[GetCharacterIndex("Konchitas")].Dialog.CurrentNode = "devushka_deal_13";  
Lai_ActorDialogNow(characterFromID("Konchitas"), Pchar, "",-1);
break;
    
case "ChurchTreasure_10":
LAi_SetActorType(characterFromID("Geneshok"));
Characters[GetCharacterIndex("Geneshok")].Dialog.CurrentNode = "manna_deal_4";  
Lai_ActorDialogNow(characterFromID("Geneshok"), Pchar, "",-1);   
break;
    
case "ChurchTreasure_11":
LAi_SetActorType(characterFromID("Konchitas"));
Characters[GetCharacterIndex("Konchitas")].Dialog.CurrentNode = "devushka_deal_14";  
Lai_ActorDialogNow(characterFromID("Konchitas"), Pchar, "",-1);
break;
    
case "ChurchTreasure_12":
LAi_SetActorType(characterFromID("Geneshok"));
Characters[GetCharacterIndex("Geneshok")].Dialog.CurrentNode = "manna_deal_10";  
Lai_ActorDialogNow(characterFromID("Geneshok"), Pchar, "",-1);
break;
    
case "ChurchTreasure_13":
Locations[FindLocation("SanSeb_port_door_4")].reload.l1.disable = false;
DoQuestReloadToLocation("SanSeb_port", "goto", "goto_24", "ChurchTreasure_14");  
break;


Locations[FindLocation("SanSeb_port_door_4")].reload.l1.disable = false; - открывает локацию, ГГ может выйти
DoQuestReloadToLocation("SanSeb_port", "goto", "goto_24", "ChurchTreasure_14"); - перемещает ГГ в локацию и перегружает исполнение case квеста, в нашем случае, ГГ переместится в локацию SanSeb_port и встанет на локатор goto_24

Код
case "ChurchTreasure_14":
ChangeCharacterAddressGroup(CharacterFromID("Geneshok"), PChar.location, "goto", "goto_25");
Lai_setActorType(Pchar);
LAi_ActorFollow(Pchar, CharacterFromID("Geneshok"), "", -1);  
Lai_setActorType(CharacterFromID("Geneshok"));
LAi_ActorFollow(CharacterFromID("Geneshok"), Pchar, "ChurchTreasure_14a", -1);  
break;


ChangeCharacterAddressGroup(CharacterFromID("Geneshok"), PChar.location, "goto", "goto_25"); - перемещает НПС в локацию к ГГ, в нашем случае, жених Кончиты оказывается на соседнем локаторе goto_25, около героя.

Код
case "ChurchTreasure_14a":
Lai_setPlayerType(Pchar);
LAi_SetActorType(characterFromID("Geneshok"));
Characters[GetCharacterIndex("Geneshok")].Dialog.CurrentNode = "manna_deal_15a";  
Lai_ActorDialogNow(characterFromID("Geneshok"), Pchar, "",-1);
break;
    
case "ChurchTreasure_15":
Lai_setPlayerType(characterFromID("Geneshok"));
ChangeCharacterAddress(characterFromID("Konchitas"), "None", "");
DoQuestCheckDelay("ChurchTreasure_16", 1.0);
break;
    
case "ChurchTreasure_16":
LAi_SetImmortal(CharacterFromID("Geneshok"), false);
LAi_SetHP(CharacterFromID("Geneshok"), 500.0, 500.0);
LAi_SetWarriorType(CharacterFromID("Geneshok"));
GiveItem2Character(CharacterFromID("Geneshok"), "gun3");
EquipCharacterByItem(CharacterFromID("Geneshok"), "gun3");
LAi_group_MoveCharacter(CharacterFromID("Geneshok"), "GENESHOKS_BANDA");
LAi_group_SetRelation("GENESHOKS_BANDA", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY);
LAi_group_FightGroups("GENESHOKS_BANDA", LAI_GROUP_PLAYER, true);  
PChar.quest.ChurchTreasure_17.win_condition.l1 = "NPC_Death";  
PChar.quest.ChurchTreasure_17.win_condition.l1.character = "Geneshok";
PChar.quest.ChurchTreasure_17.win_condition = "ChurchTreasure_17";
break;


LAi_SetImmortal(CharacterFromID("Geneshok"), false); - отменить бессмертие НПС
LAi_SetHP(CharacterFromID("Geneshok"), 500.0, 500.0); - задать НПС здоровье
LAi_SetWarriorType(CharacterFromID("Geneshok")); - сделать НПС врагом
GiveItem2Character(CharacterFromID("Geneshok"), "gun3"); - дать НПС пистоль
EquipCharacterByItem(CharacterFromID("Geneshok"), "gun3"); - разрешить пользоваться пистолем
LAi_group_MoveCharacter(CharacterFromID("Geneshok"), "GENESHOKS_BANDA"); - переместить НПС в группу, требуется только если много НПС нападают на ГГ (пишу просто по своему шаблону, поэтому у меня так)
LAi_group_SetRelation("GENESHOKS_BANDA", LAI_GROUP_PLAYER, LAI_GROUP_ENEMY); - устанавливает отношения группы, в данном случае, враждебные отношения. (можно использовать RELATION_FRIEND – дружественные отношения или RELATION_ NEUTRAL – нейтральные.)
LAi_group_FightGroups("GENESHOKS_BANDA", LAI_GROUP_PLAYER, true); - нападение группы на ГГ
PChar.quest.ChurchTreasure_17.win_condition.l1 = "NPC_Death"; - условие, смерть НПС
PChar.quest.ChurchTreasure_17.win_condition.l1.character = "Geneshok"; - id НПС который должен умереть
PChar.quest.ChurchTreasure_17.win_condition = "ChurchTreasure_17"; - название следующего case квеста который будет исполнен

Код
case "ChurchTreasure_17":
AddQuestRecord("ChurchTrs", "2");
ChangeCharacterAddress(characterFromID("Geneshok"), "None", "");
PChar.quest.ChurchTreasure_18.win_condition.l1 = "location";  
PChar.quest.ChurchTreasure_18.win_condition.l1.location = "SanSebastian_door58";
PChar.quest.ChurchTreasure_18.win_condition = "ChurchTreasure_18";
break;
    
case "ChurchTreasure_18":
Lai_setActorType(Pchar);
LAi_ActorFollow(Pchar, CharacterFromID("First Church Treas"), "", -1);  
Lai_setActorType(CharacterFromID("First Church Treas"));
LAi_ActorFollow(CharacterFromID("First Church Treas"), Pchar, "ChurchTreasure_18a", -1);  
break;
    
case "ChurchTreasure_18a":
Lai_setPlayerType(Pchar);
LAi_SetActorType(characterFromID("First Church Treas"));
Characters[GetCharacterIndex("First Church Treas")].Dialog.CurrentNode = "corn_deal_a12";  
Lai_ActorDialogNow(characterFromID("First Church Treas"), Pchar, "",-1);  
break;  
    
case "ChurchTreasure_20":
AddQuestRecord("ChurchTrs", "3");
CloseQuestHeader("ChurchTrs");
break;


CloseQuestHeader("ChurchTrs"); - закрытие название квеста в СЖ

И самое последнее, без чего не обходится ни один квест, записи в СЖ. Открываем файл quests_texts.txt (путь RESOURCE\INI\texts\russian\questbook) и добавляем туда такую запись, куда добавляем, разницы особой нет.

Код
#QUEST    ChurchTrs   //название записи в case квеста
Простая вроде история  //название квеста видимое в СЖ
#TEXT    1  // номер записи в СЖ, каждая новая добавляется сверху
Встреча со священником обернулась для меня неожиданной радостью. Взять и запросто живешь, получить 20 000 золотых. Только надо поискать девушку и отчего-то там спасти. Как он сказал, она любит морские виды
#TEXT    2
Девушку я нашел. Хотя она сама была против такой рекомендации. И жениха ее убил. Неужели это и есть, спасти девушку?
#TEXT    3
Все было не сложно. Деньги при мне, и жизнь удалась. Чем бы еще заняться в этом городе?


Вот и все. Теперь вы можете самостоятельно написать не сложный квест.

Некоторые из win_condition:

Доступно только для пользователей

Можно комбинировать win_condition (например):

Код
PChar.quest.(название case квеста 1).win_condition.l1 = "NPC_Death";
PChar.quest.(название case квеста 1).win_condition.l1.character = "id НПС";
PChar.quest.(название case квеста 1).win_condition = "(название case квеста 1)";
PChar.quest.(название case квеста 2).win_condition.l1 = "ExitFromLocation";
PChar.quest.(название case квеста 2).win_condition.l1.location = "id докации";
PChar.quest.(название case квеста 2).win_condition = "(название case квеста 2)";


Допустим должна произойти дуэль между ГГ и НПС. Прописав такое выражение в case квеста получим два разных результата: если ГГ убьет НПС запуститься case квеста 1, а если сбежит из локации, то case квеста 2

Если возникнут вопросы, то задавайте их в этой теме.

Урок написан для форума Залив Ветров.


 
ExplouTДата: Воскресенье, 05.06.2022, 15:19 | Сообщение # 4
 Рекрут
Сообщений:
1
Награды:
Репутация:
0
Замечания:
Спасибо за урок smile
 
markmorriss3010Дата: Пятница, 29.12.2023, 18:54 | Сообщение # 5
 Рекрут
Сообщений:
1
Награды:
Репутация:
0
Замечания:
Недавно смог купить Forza Motorsport (2023). Игра очень понравилась, никогда не думал что меня увлекут гонки xDD

https://ggsel.net/catalog/forza-motorsport-2023
 
Форум » Любительские модификации для "Корсаров" » Уроки по созданию модификаций » Урок: Пишем квест (сухопутный) и создаем файл для него
  • Страница 1 из 1
  • 1
Поиск:

Яндекс.Метрика