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

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

Вопросы по скриптингу

MaGoth

★★★★★★★★★★★
Администратор
Регистрация
7 Янв 2003
Сообщения
19.367
Благодарности
7.815
Баллы
995
  • Первое сообщение
  • #1
Прежде чем задавать вопросы, ознакомьтесь с документацией..
1) Читать онлайн
2) Архив с офлайн-версией(chm) во вложении
 

Вложения

  • Vam_tutor.rar
    171,6 KB · Просмотры: 573
Последнее редактирование модератором:

Vicont45

Участник форума
Регистрация
22 Авг 2011
Сообщения
248
Благодарности
70
Баллы
190
Прочел. Созрела пара вопросов:

-Имеет ли значение куда прописывать материалы порталов, или их вообще нигде прописывать не нужно?
Сначала я прописал их в фильтре Temp.pml, опасаясь попадания в ТРЭШ. Потом сунул в Portale.pml к остальным собратьям.

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

Saturas


Модостроитель
Регистрация
11 Фев 2009
Сообщения
2.512
Благодарности
1.334
Баллы
315
На счет монолитной сетки - хз, а по поводу треша - не важно
 

Feuermagier


Модостроитель
Регистрация
13 Апр 2008
Сообщения
934
Благодарности
136
Баллы
225
-Не ясно о построении геометрии: как я писал выше, у моего интерьера модульная структура, т.е. он состоит из отдельных элементов одного меша. Нужно ли сшивать ребра и вершины этих элементов в монолитную сетку??

Обязательно. Меш с порталом должен быть единой сеткой, при этом внутреннее пространство не должно прерываться или пересекаться со внешним. Любая небольшая дырка, не соединеные вершины, незначительные пересечения плоскостей приводят к косякам в помещениях с порталом.
 

Vicont45

Участник форума
Регистрация
22 Авг 2011
Сообщения
248
Благодарности
70
Баллы
190
Спасибо, учту.
А что подразумевается под таким свойством indoor, как "Правильный расчет темноты в недоступных для солнца объектах."?
Сначала я думал, что в пространстве indoor должно быть светло как днем, а оказалось темно (причем с порталом темнее, чем без него). Можно ли как нибудь, при помощи indoor обойтись без искусственных источников света?
 

MaGoth

★★★★★★★★★★★
Администратор
Регистрация
7 Янв 2003
Сообщения
19.367
Благодарности
7.815
Баллы
995
Vicont45,
indoor - подземный мир,
outdoor - наземный мир,
Что есть что, обяснений не требует надеюсь?

Можно ли как нибудь, при помощи indoor обойтись без искусственных источников света?
Не понял что ты этим хотел спросить ?!
 

Vicont45

Участник форума
Регистрация
22 Авг 2011
Сообщения
248
Благодарности
70
Баллы
190
Я имел в виду, когда загружаешь в спейсер изолированную локацию и выбираешь опцию копиляции в indoor, то не смотря на то, что она недоступна для солнца, в ней светло как днем. Так я думал, что при создании портала и компиляции всей локации как otdoor, те же свойства будут и у интерьера за порталом.

В статье http://mod.worldofgothic.ru/3d/indoor-outdoor, говорится, что indoor решает задачу "Правильного расчета темноты в недоступных для солнца объектах".
Что под этим подразумевается?
 

MaGoth

★★★★★★★★★★★
Администратор
Регистрация
7 Янв 2003
Сообщения
19.367
Благодарности
7.815
Баллы
995

Saturas


Модостроитель
Регистрация
11 Фев 2009
Сообщения
2.512
Благодарности
1.334
Баллы
315
Вопрос кароче.
Появилась необходимость вывести гг из состояния ZS_xxx, допустим нпс замораживает гг в глыбу льда, и гг переходит в состояние zs_magicfreeze, но по окончанию действия эффекта, гг из состояния не выход автоматически, на сколько я понял то AI_standup(...) на гг не действует, так как тогда перевести гг обратно в нормальное состояние?
Чисто скриптом.
Решено, всему виной своеобразная форма моих рук....
 

Sandrin

Почетный форумчанин
Регистрация
5 Авг 2009
Сообщения
8.586
Благодарности
4.047
Баллы
1.290
И снова приветствую всех.

Опять напоролась на баг. И опять в Хоране.
Ситуация: НПС (Ferell) хочет спрыгнуть со скалы, ГГ должен спасти его, заставив выпить особое зелье, спасающее от падения с высоты (т.е. делающее НПС бессмертным). Но вдобавок выпить он ему предлагает разные сорта напитков: вино, водку, пиво. Если выбрать не зелье, НПС разбивается. Если дать зелье - выживет.
Но происходит странная вещь. Даешь зелье - оно остается в инвентаре и не возникает запись, что зелье отдано, хотя опыт получаешь, НПС благодарит и благополучно разбивается, миссия провалена.
Когда даешь пиво, почему-то дается вода, когда водку - пиво, а если есть одна водка в инвентаре, то опять же не отдаешь ничего, а НПС благодарит и прыгает.

Вот скрипты этого меню:

func void kh_5008_vlk_ferell_selbstmord_springen()
{
AI_Output(other,self,"KH_5008_VLK_Ferell_SELBSTMORD_SPRINGEN_15_01"); //Ты, конечно, твердо решил прыгать... Я не буду мешать.
AI_Output(self,other,"KH_5008_VLK_Ferell_SELBSTMORD_SPRINGEN_04_02"); //Кхм... Я прыгаю, разумеется... однако... чертовски высоко...
AI_Output(other,self,"KH_5008_VLK_Ferell_SELBSTMORD_SPRINGEN_15_03"); //Вот, выпей, это придаст тебе мужества.
Info_ClearChoices(kh_5008_vlk_ferell_selbstmord);
if(Npc_HasItems(other,ItFo_Booze) >= 1)
{
Info_AddChoice(kh_5008_vlk_ferell_selbstmord,"( Дать самогон)",kh_5008_vlk_ferell_selbstmord_wachholder);
};
if(Npc_HasItems(other,ItFo_Beer) >= 1)
{
Info_AddChoice(kh_5008_vlk_ferell_selbstmord,"( Дать пиво)",kh_5008_vlk_ferell_selbstmord_bier);
};
if(Npc_HasItems(other,ItFo_Wine) >= 1)
{
Info_AddChoice(kh_5008_vlk_ferell_selbstmord,"( Дать вино)",kh_5008_vlk_ferell_selbstmord_wein);
};
if(Npc_HasItems(other,itpo_geheimnisvoller_trank) >= 1)
{
Info_AddChoice(kh_5008_vlk_ferell_selbstmord,"( Дать таинственный напиток)",kh_5008_vlk_ferell_selbstmord_trank);
};
Info_AddChoice(kh_5008_vlk_ferell_selbstmord,"Я принесу тебе что-нибудь выпить.",kh_5008_vlk_ferell_selbstmord_ende);
};

func void kh_5008_vlk_ferell_selbstmord_wachholder()
{
b_trunkanferell(self,other,6299);
AI_StopProcessInfos(self);
Info_ClearChoices(kh_5008_vlk_ferell_selbstmord);
};

func void kh_5008_vlk_ferell_selbstmord_bier()
{
b_trunkanferell(self,other,6297);
AI_StopProcessInfos(self);
Info_ClearChoices(kh_5008_vlk_ferell_selbstmord);
};

func void kh_5008_vlk_ferell_selbstmord_wein()
{
b_trunkanferell(self,other,6301);
AI_StopProcessInfos(self);
Info_ClearChoices(kh_5008_vlk_ferell_selbstmord);
};

func void kh_5008_vlk_ferell_selbstmord_trank()
{
b_trunkanferell(self,other,6593);
self.flags = NPC_FLAG_IMMORTAL;
AI_StopProcessInfos(self);
Info_ClearChoices(kh_5008_vlk_ferell_selbstmord);
};

func void kh_5008_vlk_ferell_selbstmord_ende()
{
AI_Output(other,self,"KH_5008_VLK_Ferell_SELBSTMORD_ENDE_15_01"); //Я принесу тебе что-нибудь выпить.
KH_FERELLWILLSTERBEN = 3;
KH_EINTAGBISFERELLSTOD = Wld_GetDay();
KH_EINTAGFUERFERELL = TRUE;
AI_StopProcessInfos(self);
Info_ClearChoices(kh_5008_vlk_ferell_selbstmord);
};

Вот скрипты записей в дневник на удачный и неудачный исход:

var int kh_ferellsolltawechseln;

func void b_trunkanferell(var C_Npc slf,var C_Npc oth,var int itemInstance)
{
AI_Output(slf,oth,"KH_5008_VLK_Ferell_TRUNKANFERELL_Info_04_01"); //
B_GiveInvItems(oth,slf,itemInstance,1);
if(itemInstance == 0)
{
CreateInvItems(slf,itpo_geheimnisvoller_trank_drink,1);
Npc_RemoveInvItems(slf,itpo_geheimnisvoller_trank,1);
itemInstance = 6594;
KH_FALLSCHUTZ = TRUE;
};
AI_UseItemToState(slf,itemInstance,0);
AI_UseItemToState(slf,itemInstance,-1);
AI_Output(slf,oth,"KH_5008_VLK_Ferell_TRUNKANFERELL_Info_04_02"); //
Npc_ExchangeRoutine(slf,"Spring");
KH_FERELLSOLLTAWECHSELN = TRUE;
if(KH_FALLSCHUTZ == FALSE)
{
B_LogEntry(TOPIC_KH_FERELLSSORGEN,"Я не понимаю. Этот болван действительно прыгнул. Что я наделал?");
B_GivePlayerXP(-200);
MIS_KH_FERELLSSORGEN = LOG_FAILED;
Log_SetTopicStatus(TOPIC_KH_FERELLSSORGEN,LOG_FAILED);
}
else
{
Log_AddEntry(TOPIC_KH_FERELLSSORGEN,"Я не понимаю. Этот болван действительно прыгнул. Остается надеятся, что напиток сработал.");
};
if(MIS_KH_TREFFEN == LOG_SUCCESS)
{
KH_FERELLWILLSTERBEN = 2;
}
else
{
KH_FERELLWILLSTERBEN = 1;
};
};

func void b_ferelltawechsel()
{
if(KH_FERELLSOLLTAWECHSELN == TRUE)
{
Npc_ExchangeRoutine(kh_5008_vlk_ferell,"STURZ");
KH_FERELLSOLLTAWECHSELN = FALSE;
};
};

Помогите разобраться, что здесь не так? А то исчезает один из колоритных способов решения квеста.
Заранее всех благодарю. *flowers*
 

redleha


Модостроитель
Регистрация
26 Фев 2008
Сообщения
735
Благодарности
665
Баллы
245
Ну, видимо, это ошибки декомпиляции... ввиду отсутствия функции b_trunkanferell(var C_Npc slf,var C_Npc oth,var int itemInstance) в списке переопределённых функций.
Здесь надо конкретно прописывать:
вот здесь (выделено жирным) число-номер инстанции заменять на имя инстанции, и так везде:
func void kh_5008_vlk_ferell_selbstmord_wachholder()
{
b_trunkanferell(self,other,6299); //число 6299 заменить на ItFo_Booze
AI_StopProcessInfos(self);
Info_ClearChoices(kh_5008_vlk_ferell_selbstmord);
};

а в данном случае поможет пока:
if(itemInstance == 6593)
{
CreateInvItems(slf,itpo_geheimnisvoller_trank_drink,1); //вот эта строка лишняя, судя по всему.
Npc_RemoveInvItems(slf,itpo_geheimnisvoller_trank, 1);
itemInstance = 6594;
KH_FALLSCHUTZ = TRUE;
};

а чтобы нормально и правильно компилировать с помощью GS, необходимо добавить след. строку в файл RedefinedFunc.dsc
void b_trunkanferell(instance,instance,int#);
 

Vam

Почетный форумчанин
Регистрация
8 Июл 2008
Сообщения
255
Благодарности
1
Баллы
180
а чтобы нормально и правильно компилировать с помощью GS, необходимо добавить след. строку в файл RedefinedFunc.dsc
void b_trunkanferell(instance,instance,int#);
Это относится не только к компиляции, но и к декомпиляции тоже, если будет эта запись, то в декомп. скриптах вместо циферок будут имена инстанций.
 

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
449
Благодарности
266
Баллы
230
Sandrin, конечно смешно в некоторых моментах сюжета, но...
Я так понимаю эту ситуацию:

Есть какой-то человек, который решил спрыгнуть со скалы, горы или с вышки какой-то, может с дерева.

ГГ подбирается к нему и говорит, что у него есть "чудо напиток", который облегчит твоё падение с учётом того, что твой разум будет находиться в другом месте, в то время как тело будет падать. Т.е. как бы обман разума на небольшой промежуток времени...

Если ГГ даёт "чудо напиток", то человек падает и приземляется успешно, затем встаёт и говорит: "Что это было? О, моя голова!"(как всегда).

Другие напитки лишь усугубляют всю ситуацию. Т.е. в место того, чтобы нормально слезть или хотябы договорить, тот человек просто падает вниз, да ещё и в полёте разговаривать начинает...
Например, он говорит: "Ты куда полетел, я тебя не удержу?".
А на самом деле он сам уже падает и ему кажется, что ГГ улетает от него вверх.

Итого: неудачное приземление или гибель человека.

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

Вот что удалось исправить. Конечно не идеал, т.к. некоторые переменные не понятно зачем нужны...
Такие ситуации охватывают не только скрипты, но и Спэйсер наверное.
Если бы было больше материала, функций, то можно было бы что-то придумать и слепить из них, а так.. хз, мб чем-то поможет, а мб только больше запутает.

Код:
var int kh_ferellsolltawechseln;

func void b_trunkanferell(var int itemInstance)
{
	var C_Npc her;//ГГ
	var C_NPC oth;//человек
	her = Hlp_GetNpc(PC_Hero);
	oth = Hlp_GetNpc(kh_5008_vlk_ferell);
	

	AI_Output(slf,oth,"KH_5008_VLK_Ferell_TRUNKANFEREL L_Info_04_01"); //
	B_GiveInvItems(her,oth,itemInstance,1);
	
	AI_UseItemToState(oth,itemInstance,0);//мб объединить в одну как-то можно?
	AI_UseItemToState(oth,itemInstance,-1);
	
	AI_Output(slf,oth,"KH_5008_VLK_Ferell_TRUNKANFEREL L_Info_04_02"); //
	Npc_ExchangeRoutine(oth,"Spring");
	KH_FERELLSOLLTAWECHSELN = TRUE;//???

	Log_AddEntry(TOPIC_KH_FERELLSSORGEN,"Я не понимаю. Этот болван действительно прыгнул. Остается надеятся, что напиток сработал.");

	
	if(MIS_KH_TREFFEN == LOG_SUCCESS)
	{
		KH_FERELLWILLSTERBEN = 2;
	}
	else
	{
		KH_FERELLWILLSTERBEN = 1;
	};
};

func void b_ferelltawechsel()
{
	if(KH_FERELLSOLLTAWECHSELN == TRUE)
	{
		Npc_ExchangeRoutine(kh_5008_vlk_ferell,"STURZ");
		KH_FERELLSOLLTAWECHSELN = FALSE;
	};
};


func void kh_5008_vlk_ferell_selbstmord_springen()
{
	AI_Output(other,self,"KH_5008_VLK_Ferell_SELBSTMOR D_SPRINGEN_15_01"); //Ты, конечно, твердо решил прыгать... Я не буду мешать.
	AI_Output(self,other,"KH_5008_VLK_Ferell_SELBSTMOR D_SPRINGEN_04_02"); //Кхм... Я прыгаю, разумеется... однако... чертовски высоко...
	AI_Output(other,self,"KH_5008_VLK_Ferell_SELBSTMOR D_SPRINGEN_15_03"); //Вот, выпей, это придаст тебе мужества.
	Info_ClearChoices(kh_5008_vlk_ferell_selbstmord);
	if(Npc_HasItems(other,ItFo_Booze) > 0)//dev
	{
		Info_AddChoice(kh_5008_vlk_ferell_selbstmord,"( Дать самогон)",kh_5008_vlk_ferell_selbstmord_wachholder);
	};
	if(Npc_HasItems(other,ItFo_Beer) > 0)//dev
	{
		Info_AddChoice(kh_5008_vlk_ferell_selbstmord,"( Дать пиво)",kh_5008_vlk_ferell_selbstmord_bier);
	};
	if(Npc_HasItems(other,ItFo_Wine) > 0)//dev
	{
		Info_AddChoice(kh_5008_vlk_ferell_selbstmord,"( Дать вино)",kh_5008_vlk_ferell_selbstmord_wein);
	};
	if(Npc_HasItems(other,itpo_geheimnisvoller_trank) > 0)//dev
	{
		Info_AddChoice(kh_5008_vlk_ferell_selbstmord,"( Дать таинственный напиток)",kh_5008_vlk_ferell_selbstmord_trank);
	};
	Info_AddChoice(kh_5008_vlk_ferell_selbstmord,"Я принесу тебе что-нибудь выпить.",kh_5008_vlk_ferell_selbstmord_ende);
};

func void kh_5008_vlk_ferell_selbstmord_wachholder()
{
	var int itm;//переменная для хранения ItemId предмета
	Npc_GetInvItem(other,ItFo_Booze);//создаём в глобальной переменной "item" ссылку на предмет.
	itm = Hlp_GetInstanceID(item);//получаем ItemId по глобальной ссылке
	
	b_trunkanferell(itm);//отправляем ItemId для обработки
	AI_StopProcessInfos(self);
	Info_ClearChoices(kh_5008_vlk_ferell_selbstmord);
};

func void kh_5008_vlk_ferell_selbstmord_bier()
{
	var int itm;
	Npc_GetInvItem(other,ItFo_Beer);
	itm = Hlp_GetInstanceID(item);
	
	b_trunkanferell(itm);
	AI_StopProcessInfos(self);
	Info_ClearChoices(kh_5008_vlk_ferell_selbstmord);
};

func void kh_5008_vlk_ferell_selbstmord_wein()
{
	var int itm;
	Npc_GetInvItem(other,ItFo_Wine);
	itm = Hlp_GetInstanceID(item);
	
	b_trunkanferell(itm);
	AI_StopProcessInfos(self);
	Info_ClearChoices(kh_5008_vlk_ferell_selbstmord);
};

func void kh_5008_vlk_ferell_selbstmord_trank()
{
	var int itm;
	Npc_GetInvItem(other,itpo_geheimnisvoller_trank);
	itm = Hlp_GetInstanceID(item);
	
	b_trunkanferell(itm);
	kh_5008_vlk_ferell.flags = NPC_FLAG_IMMORTAL;//dev. Скорей всего слетит при загрузке.
        //Лучше сделать переменную, а когда человек будет в цикле, пускай проверяет дано ли ему быть бессмертным или не дано.
	AI_StopProcessInfos(self);
	Info_ClearChoices(kh_5008_vlk_ferell_selbstmord);
};

func void kh_5008_vlk_ferell_selbstmord_ende()
{
	AI_Output(other,self,"KH_5008_VLK_Ferell_SELBSTMOR D_ENDE_15_01"); //Я принесу тебе что-нибудь выпить.
	KH_FERELLWILLSTERBEN = 3;
	KH_EINTAGBISFERELLSTOD = Wld_GetDay();
	KH_EINTAGFUERFERELL = TRUE;
	AI_StopProcessInfos(self);
	Info_ClearChoices(kh_5008_vlk_ferell_selbstmord);
};
И ещё, не стоит передавать параметры в функцию, если она используется для одного конкретного случая. Можно просто заранее описать эти параметры внутри, а то, что динамически меняется, то можно передать для управления.
А также лучше заменять все "0" или "1" на константы "TRUE" or "FALSE".
Проще говоря если что-то не изменяется в процессе, лучше сделать константой.
 

Sandrin

Почетный форумчанин
Регистрация
5 Авг 2009
Сообщения
8.586
Благодарности
4.047
Баллы
1.290
redleha, Vam, Jr13San, спасибо вам всем за ответы. *flowers*

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

Объяснения мне понятны на процентов 20%. Я же только переводчик, меняю фразы в скриптах, ну, компилировать-декомпилировать умею, этим и ограничиваются мои знания в моддинге.
Но постараюсь все же все применить.

Мне вот думается - ну что мододелам лень самим проверить в малюсеньком моде, как работают подобные нововведения?
 

MaGoth

★★★★★★★★★★★
Администратор
Регистрация
7 Янв 2003
Сообщения
19.367
Благодарности
7.815
Баллы
995
Sandrin,
Мне вот думается - ну что мододелам лень самим проверить в малюсеньком моде, как работают подобные нововведения?
Просто этим никто заморачиваться не станет, да и зачем, полезешь одно править, так у них там еще вагон и тележка багов нарисуется. Проще свой проект делать чем чужие баги отлавливать. + то что поляки и прочие ино-моддеры редко пользуют Сурсер в работе со скриптами, тоже влияет... :)
 

Fozar

Участник форума
Регистрация
28 Авг 2011
Сообщения
3
Благодарности
0
Баллы
145
Как в Г1 редактировать диалоги?
По адресу Gothic\_work\DATA\scripts\content\Story\MISSIONS что то есть, но это не то вот цитата:
Код:
AI_Output (other, self,"DIA_Gomez_Fault_15_00"); //Ich bin gekommen, um dir meine Dienste anzubieten.

На русские субтитры не похоже
 

MaGoth

★★★★★★★★★★★
Администратор
Регистрация
7 Янв 2003
Сообщения
19.367
Благодарности
7.815
Баллы
995
Fozar, Эм...
1. откуда ты это выкопал?
2. какая у тебя версия игры локализация?
3. все что касается скриптов и скриптинга расписано тут: https://worldofplayers.ru/moddb
 

Fozar

Участник форума
Регистрация
28 Авг 2011
Сообщения
3
Благодарности
0
Баллы
145
.

1. в каком то гайде
2. 1.08
3. там почти все к г2

Например Здесь:

DECOMPILED\_work\data\Scripts\_decompiled\Items - вот где это

На вопрос забили?
 

xterm

Участник форума
Регистрация
25 Июн 2009
Сообщения
5.178
Благодарности
16
Баллы
400
Fozar

1. За даблпостинг и флуд получаешь предупреждение..Посты объединил, тебе советую прочитать правила форума.
2. Поискать любое слово в проекте не пробовал? Вбиваешь в поиск слово лук, маг или Диего и ищешь файл.
 

GothMass


Модостроитель
Регистрация
4 Окт 2010
Сообщения
336
Благодарности
314
Баллы
220
Ребят, как в файле Startup.d прописать новый мир, с новыми нпс?
 
Сверху Снизу