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

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

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

MaGoth

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

Вложения

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

Ilot

Участник форума
Регистрация
17 Сен 2010
Сообщения
798
Благодарности
297
Баллы
245
Блин, Dimmell, сижу на работе. Как я по вашему проверю? Вчера поставил задачу, как сделать сразу не сообразил да и сейчас плохо понимаю... вот и спрашиваю совета бывалых. Что здесь плохого?

Хм.. не знал что у меня авторитет бездльника;).
 

Dimmell

Участник форума
Регистрация
23 Ноя 2008
Сообщения
2.899
Благодарности
111
Баллы
285
Ilot,
Блин, Dimmell, сижу на работе. Как я по вашему проверю?
ну а как я по вашему проверю, если у меня Готики вообще нет? :D
А вообще-то распишите конкретно что вы хотите сделать:
Вопросик назрел: есть ли возможность скриптами удалить объект из мира? В частности мне необходимо удалить PFX.
- это не постановка задачи, а сиюминутная прихоть. :)
Если хотите добавить/удалить объект - только мувер нормально и безглючно отработает.
ЗЫ. Вполне возможно что все-таки придется "задачу" подкорректировать под возможности двига, а не наоборот.
ЗЫЫ. Есть еще вариант Сатураса подергать, может он чего выродит. :D
 

Ilot

Участник форума
Регистрация
17 Сен 2010
Сообщения
798
Благодарности
297
Баллы
245

ErikDK

Участник форума
Регистрация
11 Янв 2012
Сообщения
25
Благодарности
1
Баллы
165
Наверное очень нубский вопрос. Не выходит сделать зацикленный скрипт с помощью триггера. Делаю всё один в один по тутору но чего то там не хватает. Компилятор ругается на
Wld_SendTrigger(CYCLE_TRIGGER);
Ошибка: Неизвестный идентификатор: CYCLE_TRIGGER
К сожалению нет ничего аналогичного в скриптах, потому не смог сам разобраться. Что там ещё нужно добавить?
 

Ilot

Участник форума
Регистрация
17 Сен 2010
Сообщения
798
Благодарности
297
Баллы
245
ErikDK, сам когда то столкнулся с этой проблемой. Решил так.
В Story_Globals вставляешь строчку:
const string CYCLE_TRIGGER = "CYCLE_TRIGGER";
 

Myxomop

Почетный форумчанин
Регистрация
28 Май 2005
Сообщения
3.238
Благодарности
2.579
Баллы
455
ErikDK,
Поставь в кавычки.
Wld_SendTrigger("CYCLE_TRIGGER");
 

Dimmell

Участник форума
Регистрация
23 Ноя 2008
Сообщения
2.899
Благодарности
111
Баллы
285
Ilot,
//------------- Этот блок не работает !!! ----------------------

Как написан - так и работает.
Разберем по порядку:
1. надо украсть овцу
например, если мы ближе чем 5м к овце if (Npc_GetDistToNpc (Baran_1001, hero):
Npc_ExchangeRoutine (Baran_1001, "Follow");
PrintScreen ("Я украл овцу!!! Пора делать ноги...", -1, YPOS_LOGENTRY, FONT_ScreenSmall_Rot, 4);
varBarFollow = true; //переменная - баран идет за ГГ
И не надо "странных диалогов" с овцой.
2 обработка восприятий сторожа:
Npc_CanSeeNpc (c_npc npc1, c_npc npc2); - видит
или Npc_HasDetectedNpc (c_npc self, c_npc other); - чувствует (видит, сышит и т.д.)
на вкус.
И не надо привязывать к расстоянию, куча непоняток может быть при игре.
Если не увидел - уводим барана из-под носа, дальше - по сюжету.
Если увидел и varBarFollow = true;:
Npc_ExchangeRoutine (BAU_5000_Ardan, "Follow");
PrintScreen ("Похоже Ардан меня заметил!", -1, YPOS_LOGENTRY, FONT_ScreenSmall_Rot, 4);
varPresled = true; //переменная - Ардан преследует ГГ

Отдельная проверка:
1.Если преследует и ГГ с овцой смотался (превышение дальности преследования) - возврат Ардана на старую рутину
Npc_ExchangeRoutine (BAU_5000_Ardan, "Start");
можно и восприятия почистить если это надо далее по квестам
2. Если пытался украсть, но спалили - проверка текущей рутины через переменные и смена ее на
Npc_ExchangeRoutine (BAU_5000_Ardan, "Start"); обнуление переменных или что там еще согласно квесту.
3. закрыл квест - обнуление переменных отвечающих за проверку кражи и преследование.
Возможно еще нужны будут отдельные проверки (типа баран - труп, сторож - труп), от сюжета зависит.
Можно добавить кражу через сник, нарисовать сетку из 3-4 WP для сторожа и пустить его гулять по ней и т.д., чтоб хоть кража - на кражу похожа была. А не "привет, баран, я тебя украл..."
Не надо использовать то, о чем не имеете представления как оно работает и зачем вообще надо. Все регулируется через простые переменные, надо только представлять что должен делать НПС в определенный игровой момент и вовремя возвращать в исходное состояние.
ЗЫ. и циклический триггер для восприятий не нужен, реакцию на кражу можно обработать через B_AssessPlayer(), более корректно будет.
 

Ilot

Участник форума
Регистрация
17 Сен 2010
Сообщения
798
Благодарности
297
Баллы
245
Dimmell, спасибо. Многое из того, что вы написали может пригодится, но вопрос не в том как реализовать - это у меня получается (кстати у меня было реализованно через ф-ю Npc_HasDetectedNpc (c_npc self, c_npc other), но позже переделал под конечный вариант для простоты - что-то там у меня не клеелось...) .
А теперь еще раз вопрос: все скрипты срабатывают нормально только один раз. При повторном похищении овечки Ардан стоит на месте. Однако если подойти к нему на дистанцию диалога - диалог срабатывает нормально. Может там какая-то очередь сотояний или реакций есть не позволяющая выполнять второй раз распорядок "Follow"?...
Не надо использовать то, о чем не имеете представления как оно работает и зачем вообще надо
BAU_5000_Ardan.aivar[AIV_TAPOSITION] = FALSE;//что за ерунда не понятно, но как то помогает..
Без этой строчки нпс не возвращается на свою точку после преследования.
P.S.
//------------- Этот блок не работает !!! ----------------------
Это просто мои комменты. Что называется для себя.
 

Dimmell

Участник форума
Регистрация
23 Ноя 2008
Сообщения
2.899
Благодарности
111
Баллы
285
Ilot,
Без этой строчки нпс не возвращается на свою точку после преследования.
Чтобы без этой строчки работало - должно быть выполнено маленькое требование: эта точка должна быть связана с мировым вайнетом.
Посмотрите скрипты Лареса, там все понятно написано и в зене проверьте как он может добраться до контрольных точек своих рутин.
Если хотите использовать BAU_5000_Ardan.aivar[AIV_TAPOSITION] попытайтесь объяснить движку что должен делать НПС когда он придет на свою позицию. Это не для использования в циклическом триггере. Если уж используете ее - пишите новый цикл по типу ZS (поиск по проекту по запросу aivar[AIV_TAPOSITION] снимет кучу вопросов).
 

Ilot

Участник форума
Регистрация
17 Сен 2010
Сообщения
798
Благодарности
297
Баллы
245
Вопрос: возможно ли через скрипты изменить урон от огня в единицу времени (имеется ввиду огненные ящеры)?
 

Dimus

★★★★★★★★★
Супермодератор
Регистрация
19 Июл 2010
Сообщения
5.563
Благодарности
4.157
Баллы
915
В процессе оптимизации скриптов аддона "Ночь Ворона" я написал 2 функции, являющиеся аналогами функций C_Beklauen() и B_Beklauen(), чтобы ГГ мог проверить возможность кражи предмета (или несколько предметов) у NPC и украсть этот предмет (эти предметы):
Код:
func int C_StealItems(var int TheftDex, var C_Item Itm, var int Qty)
{
	if((Npc_GetTalentSkill(other,NPC_TALENT_PICKPOCKET) == TRUE) && (self.aivar[AIV_PlayerHasPickedMyPocket] == FALSE) && (other.attribute[ATR_DEXTERITY] >= (TheftDex - Theftdiff)) && (Npc_HasItems(self,Itm) >= Qty))
	{
		return TRUE;
	};

};

func void B_StealItems(var int TheftDex, var C_Item Itm, var int Qty)
{
	if(other.attribute[ATR_DEXTERITY] >= TheftDex)
	{
		B_GiveInvItems(self,other,Itm,Qty);
		self.aivar[AIV_PlayerHasPickedMyPocket] = TRUE;
		B_GiveThiefXP();
	}
	else
	{
		B_ResetThiefLevel();
		AI_StopProcessInfos(self);
		B_Attack(self,other,AR_Theft,1);
	};
};
В скриптах диалогов с NPC эти функции вызываются таким образом (DIA_VLK_402_Richter.d):
Код:
instance DIA_Richter_PICKPOCKET(C_Info)
{
	npc = VLK_402_Richter;
	nr = 900;
	condition = DIA_Richter_PICKPOCKET_Condition;
	information = DIA_Richter_PICKPOCKET_Info;
	permanent = TRUE;
	description = Pickpocket_40_Key;
};


func int DIA_Richter_PICKPOCKET_Condition()
{
	return C_StealItems(30,ItKe_Richter,1);
};

func void DIA_Richter_PICKPOCKET_Info()
{
	Info_ClearChoices(DIA_Richter_PICKPOCKET);
	Info_AddChoice(DIA_Richter_PICKPOCKET,Dialog_Back,DIA_Richter_PICKPOCKET_BACK);
	Info_AddChoice(DIA_Richter_PICKPOCKET,DIALOG_PICKPOCKET,DIA_Richter_PICKPOCKET_DoIt);
};

func void DIA_Richter_PICKPOCKET_DoIt()
{
	B_StealItems(30,ItKe_Richter,1);
	Info_ClearChoices(DIA_Richter_PICKPOCKET);
};

func void DIA_Richter_PICKPOCKET_BACK()
{
	Info_ClearChoices(DIA_Richter_PICKPOCKET);
};
Но в итоге оказалось, что не работают обе функции: или не срабатывает условие в C_StealItems() и в меню не появляется диалог карманной кражи, или в функции B_StealItems ГГ не получает украденный предмет. Неужели нельзя передавать в качестве параметра функции переменную типа C_Item?*???*
 

НастасьСанна

Участник форума
Регистрация
6 Дек 2012
Сообщения
351
Благодарности
521
Баллы
325
Натыкалась на эти грабли=(
Как я поняла, в качестве C_Item передается ссылка на конкретный предмет, имеющий место быть в игровом мире, а не на описание инстанции. Поэтому, если передавать сюда имя инстанции, могут быть баги, если предмета нет в игровом мире и у него нет экземпляра.
Нормально срабатывает, например, когда передаешь имя инстанции в ее обработчике onstate, или если передавать результат возвращаемый функциями Npc_GetReadiedWeapon и т.п.
 

redleha


Модостроитель
Регистрация
26 Фев 2008
Сообщения
735
Благодарности
665
Баллы
245
Dimus, действительно не стОит передавать в таком виде, только в виде инстанции передавать надо. C_Item можно передавать желательно только , если вещь уже есть в мире и только в единственном экземпляре. ;)
 

Dimus

★★★★★★★★★
Супермодератор
Регистрация
19 Июл 2010
Сообщения
5.563
Благодарности
4.157
Баллы
915
Т.е. вы хотите сказать, что нужно действовать так?
Объявление:
Код:
func int C_StealItems(var int TheftDex, var int Itm, var int Qty)
{
	if((Npc_GetTalentSkill(other,NPC_TALENT_PICKPOCKET) == TRUE) && (self.aivar[AIV_PlayerHasPickedMyPocket] == FALSE) && (other.attribute[ATR_DEXTERITY] >= (TheftDex - Theftdiff)) && (Npc_HasItems(self,Itm) >= Qty))
	{
		return TRUE;
	};

};

func void B_StealItems(var int TheftDex, var int Itm, var int Qty)
{
	if(other.attribute[ATR_DEXTERITY] >= TheftDex)
	{
		B_GiveInvItems(self,other,Itm,Qty);
		self.aivar[AIV_PlayerHasPickedMyPocket] = TRUE;
		B_GiveThiefXP();
	}
	else
	{
		B_ResetThiefLevel();
		AI_StopProcessInfos(self);
		B_Attack(self,other,AR_Theft,1);
	};
};
Вызов:
Код:
instance DIA_Richter_PICKPOCKET(C_Info)
{
	npc = VLK_402_Richter;
	nr = 900;
	condition = DIA_Richter_PICKPOCKET_Condition;
	information = DIA_Richter_PICKPOCKET_Info;
	permanent = TRUE;
	description = Pickpocket_40_Key;
};


func int DIA_Richter_PICKPOCKET_Condition()
{
	return C_StealItems(30,Hlp_GetInstanceID(ItKe_Richter),1);
};

func void DIA_Richter_PICKPOCKET_Info()
{
	Info_ClearChoices(DIA_Richter_PICKPOCKET);
	Info_AddChoice(DIA_Richter_PICKPOCKET,Dialog_Back,DIA_Richter_PICKPOCKET_BACK);
	Info_AddChoice(DIA_Richter_PICKPOCKET,DIALOG_PICKPOCKET,DIA_Richter_PICKPOCKET_DoIt);
};

func void DIA_Richter_PICKPOCKET_DoIt()
{
	B_StealItems(30,Hlp_GetInstanceID(ItKe_Richter),1);
	Info_ClearChoices(DIA_Richter_PICKPOCKET);
};

func void DIA_Richter_PICKPOCKET_BACK()
{
	Info_ClearChoices(DIA_Richter_PICKPOCKET);
};
 

Dimmell

Участник форума
Регистрация
23 Ноя 2008
Сообщения
2.899
Благодарности
111
Баллы
285
Dimus,
Неужели нельзя передавать в качестве параметра функции переменную типа C_Item?
в функции
func int B_GiveInvItems(var C_Npc giver,var C_Npc taker,var int itemInstance,var int amount)
а вы пытаетесь передать в нее var C_Item Itm
Аналогично и с функцией C_StealItems(30,ItKe_Richter,1) - прописана ItKe_Richter (itemInstance), а вы пытаетесь работать с ней как с классом.
 

НастасьСанна

Участник форума
Регистрация
6 Дек 2012
Сообщения
351
Благодарности
521
Баллы
325
Dimus,
у меня так и не получилось реализовать подобную функцию, чтобы в нее можно было передавать C_Item как параметр. В итоге я действия-проверки конкретного предмета вынесла из этих функций, а в них оставила самое общее.
т.е. из C_StealItems убираем последнее условие, а в условии диалога пишем:
func int DIA_Richter_PICKPOCKET_Condition()
{
if (C_StealItems(30) && (Npc_HasItems(self,ItKe_Richter) >= 1))
{
return TRUE;
};
};

а B_StealItems убираем строчку про получение предмета и переписываем, чтобы она возвращала TRUE, если предмет успешно украден, FALSE - если нет, используем так:
if (B_StealItems(30))
{
B_GiveInvItems(self,other,ItKe_Richter,1);
};
 

Dimus

★★★★★★★★★
Супермодератор
Регистрация
19 Июл 2010
Сообщения
5.563
Благодарности
4.157
Баллы
915
НастасьСанна, зачем такие сложности? После переделки этих функций и обращений к ним по образцу из ответа №1645 стала работать кража предметов у почти всех персонажей, кроме Кавалорна, которому в итоге пришлось вернуть исходный код функции DIA_Addon_Cavalorn_PICKPOCKET_DoIt().
 

НастасьСанна

Участник форума
Регистрация
6 Дек 2012
Сообщения
351
Благодарности
521
Баллы
325
Dimus,
не вижу в своем варианте ничего сложного. Если через Hlp_GetInstanceID работает - очень хорошо и спасибо, буду иметь в виду. Я не была в этом уверена и предложила альтернативу, которая у меня гарантировано работает.
Насчет Кавалорна - может у него просто нет стрел для кражи в инвентаре? Но, помнится, были и другие персонажи, у которых украдываемого предмета при себе не было, Саландрил, например.
 

Dimus

★★★★★★★★★
Супермодератор
Регистрация
19 Июл 2010
Сообщения
5.563
Благодарности
4.157
Баллы
915
В том то и дело, что для подстраховки я создавал нужное количество стрел у Бартока и Кавалорна. У первого всё воруется без проблем, а у второго украденные стрелы почему-то не попадают в инвентарь ГГ и показывается надпись: 44 предметов получено (). Вот скрипты Бартока и Кавалорна:
Story\Dialoge\DIA_VLK_440_Bartok.d:
Код:
instance DIA_Bartok_PICKPOCKET(C_Info)
{
	npc = VLK_440_Bartok;
	nr = 900;
	condition = DIA_Bartok_PICKPOCKET_Condition;
	information = DIA_Bartok_PICKPOCKET_Info;
	permanent = TRUE;
	description = "(Украсть его колчан со стрелами будет просто)";
};


func int DIA_Bartok_PICKPOCKET_Condition()
{
	return C_StealItems(30,Hlp_GetInstanceID(ItRw_Arrow),0);
};

func void DIA_Bartok_PICKPOCKET_Info()
{
	Info_ClearChoices(DIA_Bartok_PICKPOCKET);
	Info_AddChoice(DIA_Bartok_PICKPOCKET,Dialog_Back,DIA_Bartok_PICKPOCKET_BACK);
	Info_AddChoice(DIA_Bartok_PICKPOCKET,DIALOG_PICKPOCKET,DIA_Bartok_PICKPOCKET_DoIt);
};

func void DIA_Bartok_PICKPOCKET_DoIt()
{
	CreateInvItems(self,ItRw_Arrow,40);
	B_StealItems(30,Hlp_GetInstanceID(ItRw_Arrow),40);
	Info_ClearChoices(DIA_Bartok_PICKPOCKET);
};

func void DIA_Bartok_PICKPOCKET_BACK()
{
	Info_ClearChoices(DIA_Bartok_PICKPOCKET);
};
Story\Dialoge\DIA_BAU_4300_Addon_Cavalorn.d:
Код:
instance DIA_Addon_Cavalorn_PICKPOCKET(C_Info)
{
	npc = BAU_4300_Addon_Cavalorn;
	nr = 900;
	condition = DIA_Addon_Cavalorn_PICKPOCKET_Condition;
	information = DIA_Addon_Cavalorn_PICKPOCKET_Info;
	permanent = TRUE;
	description = "(Нет ничего проще, чем украсть его колчан стрел)";
};


func int DIA_Addon_Cavalorn_PICKPOCKET_Condition()
{
	return C_StealItems(25,Hlp_GetInstanceID(ItRw_Arrow),0);
};

func void DIA_Addon_Cavalorn_PICKPOCKET_Info()
{
	Info_ClearChoices(DIA_Addon_Cavalorn_PICKPOCKET);
	Info_AddChoice(DIA_Addon_Cavalorn_PICKPOCKET,Dialog_Back,DIA_Addon_Cavalorn_PICKPOCKET_BACK);
	Info_AddChoice(DIA_Addon_Cavalorn_PICKPOCKET,DIALOG_PICKPOCKET,DIA_Addon_Cavalorn_PICKPOCKET_DoIt);
};

func void DIA_Addon_Cavalorn_PICKPOCKET_DoIt()
{
	CreateInvItems(self,ItRw_Arrow,44);
	B_StealItems(25,Hlp_GetInstanceID(ItRw_Arrow),44);
	Info_ClearChoices(DIA_Addon_Cavalorn_PICKPOCKET);
};
Разумеется, что изначально я не давал им стрел в скриптах Story\NPC\VLK_440_Bartok.d и Story\NPC\BAU_4300_Addon_Cavalorn.d. Также я без проблем воровал целебный эликсир у Цуриса и ключ от монастырской сокровищницы у Горакса, которых изначально нет в инвентаре этих NPC (чтобы эти предметы не попали на продажу).
 

НастасьСанна

Участник форума
Регистрация
6 Дек 2012
Сообщения
351
Благодарности
521
Баллы
325
Dimus, загадочно... По идее, должно работать, даже если не создавать стрелы, а поди ж ты, не хочет. Поэтому мне свой способ и нравится.
Сейчас вспомнила, что использовала похожую конструкцию в другом месте, и вроде бы работает, но до сих пор трясусь над этим участком. Так что решение вопроса меня тоже интересует.
 
Сверху Снизу