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

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

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

MaGoth

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

Вложения

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

Saturas


Модостроитель
Регистрация
11 Фев 2009
Сообщения
2.512
Благодарности
1.334
Баллы
315
приставка Inv_Back_ и файлик Inv_Desk вроди относяца к текстурам инвертаря.
 

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
449
Благодарности
266
Баллы
230
Вопрос:
Почему не работает функция Npc_GetLookAtTarget() в данном коде:
var C_Npc target;
target = Npc_GetLookAtTarget(hero);
PrintScreen(IntToString(target.name),-1,-1,FONT_Screen,1);


Функция работает постоянно, в таймере(для теста).
Такая вроде ответственная функция, а сделана криво и не поймёшь как работает...
Такое чувство, что она вообще не работает.
Как вывести информацию о НПС, на которого смотрит другой НПС?
 

redleha


Модостроитель
Регистрация
26 Фев 2008
Сообщения
735
Благодарности
665
Баллы
245
Вопрос:
Почему не работает функция Npc_GetLookAtTarget() в данном коде:
var C_Npc target;
target = Npc_GetLookAtTarget(hero);
PrintScreen(IntToString(target.name),-1,-1,FONT_Screen,1);
Что-то не понятно, как ты применяешь преобразование IntToString(target.name); Ведь C_NPC.name - это string.
Тогда уж просто PrintScreen(target.name,-1,-1,FONT_Screen,1);
 

HeDeDe

Участник форума
Регистрация
17 Авг 2009
Сообщения
203
Благодарности
79
Баллы
180
Jr13San, эта функция возвращает НПС, на которого смотрит переданный в нее НПС, а не НПС который находится в фокусе.

Ну и IntToString здесь лишний:
PrintScreen(target.name,-1,-1,FONT_Screen,1);

Вот так эта функция будет работать:
var C_Npc target;
AI_LookAtNpc(self,hero)
target = Npc_GetLookAtTarget(self);
PrintScreen(target.name,-1,-1,FONT_Screen,1);
 

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
449
Благодарности
266
Баллы
230
Да, извините, забыл исправить после теста. Там был сначала id.
Hedede, да, действительно, функция работает, но толку мало от того, что на ГГ смотрят.
Нужно получить ссылку на того, на кого ГГ смотрит.
А зачем тебе это собно?
Изучи глубже скриптинг и ты сам догадаешься зачем она нужна.
Многих нужных функций просто нету в движке - это трещины для модостроителей, которые приходится всё время замазывать...

Dimmell, все функции бесполезны в данном случае. Вот стоит ГГ, повёрнутый боком к НПС1 и смотрит на НПС2.
Npc_CanSeeNpc = ГГ может видеть обоих
Npc_CanSeeNpcFreeLOS - бесполезно использовать на близком расстоянии + на открытой местности.(лучше использовать когда есть препятствия)
Npc_GetDistToNpc - дистанцию тоже можно отфильтровать. Ну близко он стоит а толку то?
В итоге получается путаница, т.к. нету конкретного ограничения по каким-либо параметрам. НА обоих НПС будет реакция, что ГГ на них смотрит.
Персепшон - там тоже нету ничего хорошего.

Похоже, что эта трещина слишком большая...
 

Dimmell

Участник форума
Регистрация
23 Ноя 2008
Сообщения
2.899
Благодарности
111
Баллы
285
Jr13San,
есть куча функций в зависимости от того, что хочется получить:
int Npc_CanSeeNpc (c_npc npc1, c_npc npc2); - возвращает TRUE, если npc1 может видеть npc2, иначе – FALSE.
int Npc_CanSeeNpcFreeLOS (c_npc self, c_npc other); - возвращает TRUE, если НПС self может видеть НПС other по прямой, без учета угла обзора, иначе – FALSE.
int Npc_HasDetectedNpc (c_npc self, c_npc other); - возвращает 1, если НПС self чувствует (видит, сышит и т.д.) НПС other, иначе – 0.
int Npc_IsNear (c_npc self, c_npc other); - возвращает 1, если НПС other находится на расстоянии не менее 3 метров от НПС self, иначе – 0.
int Npc_GetDistToNpc (c_npc npc1, c_npc npc2); - возвращает расстояние в см. между npc1 и npc2.
int Npc_GetTarget (c_npc self); - возвращает TRUE, если НПС self имеет цель для поражения (в качестве цели выступает НПС other), иначе – FALSE.
int Npc_GetNextTarget (c_npc self); - выполняется активный поиск цели для НПС self. Если цель находится, то она становится внутренней целью и записывается в переменную
other, если цель не найдена, то внутренняя цель удаляется и other становится недействительным. Критерий поиска цели - в качестве цели возмется враждебный противник, который не мертв или находится не в бессознательном состоянии. Возвращает TRUE, если цель найдена, иначе – FALSE. Внимание: Поиск основывается на активном восприятии НПС self, поэтому, если активное восприятие не установлено, то сначала следует применять функцию Npc_PerceiveAll ().
int Npc_IsNextTargetAvailable (c_npc self); - работает аналогично предыдущей функции, только ни внутренняя цель, ни переменная other не инициализируются.
int Npc_IsAiming (c_npc self, c_npc other); - возвращает 1, если НПС other целится в НПС self из оружия дальнего радиуса поражения или магией, иначе – 0.
+ обработчики дальнсти и восприятий.
И не забывай что ближайшая цель захватывается автоматически в пределах восприятий диалога (дальности оружия) если ГГ ее видит или смотрит в ее направлении.

Jr13San,
есть такие функции
int Wld_DetectNpc (c_npc self, int instance, func aiState, int guild); - эта функция инициализирует глобальную переменную скриптов other, отличную от НПС self, где instance – производная от класса c_npc, которая должна быть найдена и проинициализирована (-1 – любая производная), guild – гильдия, членом которой должен быть искомый НПС (-1 – любая гильдия), aiState – функция AI состояния, в котором должен находится искомый НПС (NOFUNC – любое AI состояние). Функция возвращает 1 в случае успешного завершения (other инициализирован найденным НПС), 0 – неудача (other не определен).
int Wld_DetectNpcEx (c_npc self, int instance, func aiState, int guild, int detectPlayer); - выполняет все тоже, что и предыдущая функция, дополнительный параметр detectPlayer указывает, исключить ли игрока (ГГ) из поиска (0 – исключить, 1 – нет).
Ты определись ситуационно что тебе надо и смоделируй это так, как можно реализовать. Или у тебя НПС будет бегать по всему миру и в рот всем заглядывать? Кто вовремя откроет - с тем и поговорит. :D
 

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
449
Благодарности
266
Баллы
230
Dimmel, да нет, я хотел получить ссылку на НПС, который под фокусом во время срабатывания функции обыска трупов. Это всё нужно для более детальной обработки. Придётся эмулировать всю ситуацию другими способами.

На счёт Wld_DetectNpc() могу сказать так:
Есть 2 волка, лежат рядом и кого она проинициализирует? Наверное того, у кого номер instance меньше, а это не выход.

Кстати, не заметили почему при снятии шкуры с волка, например, она у него остаётся? Бесконечное производство или нельзя показывать детям кровь и мясо?

На чет бесконечных шкур, гдето ошибсо в скрипте.
Та нет, там прикол в том, что моделька волка остаётся в шкуре, когда по идее ГГ с него снял её(ну мысленно:)).

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

Вариматас

Забанен
Регистрация
11 Апр 2011
Сообщения
175
Благодарности
1
Баллы
165
Dimmel, да нет, я хотел получить ссылку на НПС, который под фокусом во время срабатывания функции обыска трупов. Это всё нужно для более детальной обработки. Придётся эмулировать всю ситуацию другими способами.

На счёт Wld_DetectNpc() могу сказать так:
Есть 2 волка, лежат рядом и кого она проинициализирует? Наверное того, у кого номер instance меньше, а это не выход.

Кстати, не заметили почему при снятии шкуры с волка, например, она у него остаётся? Бесконечное производство или нельзя показывать детям кровь и мясо?

На чет бесконечных шкур, гдето ошибсо в скрипте.
Кароче ты хочешь что-бы обысканный нпс не попадал в фокус?
 

Dimmell

Участник форума
Регистрация
23 Ноя 2008
Сообщения
2.899
Благодарности
111
Баллы
285
Есть 2 волка, лежат рядом и кого она проинициализирует? Наверное того, у кого номер instance меньше, а это не выход.
Ближайшего по расстоянию до него :)
Кстати, не заметили почему при снятии шкуры с волка, например, она у него остаётся? Бесконечное производство или нельзя показывать детям кровь и мясо?
Ну значит пробуем подменить модельку после обыска трупа. И напиши, что получилось. *flowers*
Вся проблема только в одном - в автонаведении ГГ движком на цель и захвате ее, будь то враг, друг и т.д. А вот сбить это автонаведение можно только через переделку двига. Других вариантов я пока не нашел.
 

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
449
Благодарности
266
Баллы
230
Ближайшего по расстоянию до него :)
Ну тут хз. В окружности есть радиус. Почему бы ГГ не быть точкой в центре этой окружности, а 2-м нпс быть по радиусу, что тогда? Вот так вот. Вариант с фокусом отбрасывается.

Ну значит пробуем подменить модельку после обыска трупа. И напиши, что получилось. *flowers*
Думаю тут нужно подменить текстурку, а вот когда ГГ будет отрезать мясо, тогда уже модельку + текстурку. Попробую сделать, как будет время...

Вся проблема только в одном - в автонаведении ГГ движком на цель и захвате ее, будь то враг, друг и т.д. А вот сбить это автонаведение можно только через переделку двига. Других вариантов я пока не нашел.

Я тут заглянул в CAMAERA.dat и увидел там несколько разных инстанций фокуса с настройками автонаведения. Там и тангаж и азимут и различные повороты. Ещё есть в стандартном Gothic.dat несколько инстанций класса C_FOCUS.
Только большинство или даже все эти инстанции используются движком по константным названиям. Т.е. это говорит о (статике & динамике=ни то - ни сё.) движка.
 

Вариматас

Забанен
Регистрация
11 Апр 2011
Сообщения
175
Благодарности
1
Баллы
165
Ближайшего по расстоянию до него :)

Ну значит пробуем подменить модельку после обыска трупа. И напиши, что получилось. *flowers*
Вся проблема только в одном - в автонаведении ГГ движком на цель и захвате ее, будь то враг, друг и т.д. А вот сбить это автонаведение можно только через переделку двига. Других вариантов я пока не нашел.

А что мешает подправить двиг? Есть G2Ext, если сильно по стараться то все получится.
 

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
449
Благодарности
266
Баллы
230
Т.к. функции UnEquipItem() нет, пишу вопрос:
"Возможно ли максимально простым способом снять выделение с вещи, кроме оружия и брони?"
Можно конечно прописать требуемые параметры для предмета при ношении. Например силу, ловкость и т.д. И в функциях Equip() и UnEquip() работать с этими значениями. Ещё придётся ставить дополнительные условия, чтобы надписей лишних не было. Т.е. меняем параметр и предмет сам снимается, т.к. недостаточно навыка. Вроде как должно работать.
Но это слишком муторно и не очень хорошо выглядеть будет.

Можно ещё воспользоваться самими флагами вещи и менять динамически её параметры. НО! При загрузке проекта, вновь предмет станет выделенным. И тогда придётся ставить таймер, чтобы следил постоянно за этим делом. Опять же всё усложняется.

У кого есть какие варианты?
 

kraw


Модостроитель
Регистрация
11 Окт 2005
Сообщения
2.095
Благодарности
871
Баллы
295
М. б. сработает "удалить из инвентаря"? А потом вернуть этот предмет в инвентарь.
 

Dimmell

Участник форума
Регистрация
23 Ноя 2008
Сообщения
2.899
Благодарности
111
Баллы
285
Jr13San,
можно попробовать
int Npc_GetInvItemBySlot (c_npc self, int category, int slotNr); - возвращает кол- во предметов, которые находятся у НПС self, где category – категория инвентаря (INV_WEAPON, INV_ARMOR, INV_RUNE, INV_MAGIC, INV_FOOD, INV_POTION, INV_DOC, INV_MISC), slotNr – номер слота предмета.

если всех предметов 0 и НПС труп - переименовать имя НПС в "" (нулевое). Естественно в триггере.

kraw,
вся беда в том, что независимо есть что-то в инвентаре, или нет - труп подсвечивается.
 

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
449
Благодарности
266
Баллы
230
Жаль, что мысля приходит опосля...
А мысля в том, чтобы "удалить, а потом опять вставить". Думаю - это самый легкий способ.
+1 всем, кто также подумал.
+2 всем, кто знает как ещё короче сделать:)
Как всегда мысль прилетает после того, как напишу вопрос. Не даром пишут: "jr13san, тебе не надоело самому себе на вопросы отвечать?"

Dimmell, да не, тут дело было в том, чтобы снять одетую вещь. Но некоторые вещи не имеют визуализации на теле ГГ. Поэтому та вещь, что я использую - служит лишь для взаимодействия с ней. Для удобства она не имеет анимации взаимодействия "scenename" кажись, но имеет выделение(создаёт красный фон на заднем плане). И после взаимодействия с ней, этот план и остаётся красным. Для следующего взаимодействия приходится снимать выделение и опять ставить.

На счёт подсветки трупа - я даже не знаю где это можно использовать. Мне в моих тестах вроде как нет такой необходимости.
func void UnEquipItem(var C_NPC npc, var C_ITEM itm)
{
Npc_RemoveInvItem(npc,Hlp_GetInstanceID(itm));//удаляем предмет
CreateInvItem(npc,Hlp_GetInstanceID(itm));//создаём предмет
};

func void UnEquipItems(var C_NPC npc, var C_ITEM itm)
{
var int QItems;
QItems = Npc_HasItems(npc,Hlp_GetInstanceID(itm));//сохраняем кол-во в памяти
Npc_RemoveInvItems(npc,Hlp_GetInstanceID(itm),QItems);//удаляем предметы
CreateInvItems(npc,Hlp_GetInstanceID(itm),QItems);//создаём предметы
};
Можно сократить кол-во символов в функциях, используя дополнительную переменную для хранения инстанции предмета.
Работает всё быстро и правильно. С мульти-предметами не тестировал.
 

Dimmell

Участник форума
Регистрация
23 Ноя 2008
Сообщения
2.899
Благодарности
111
Баллы
285
Jr13San,
предыдущие твои вопросы были связаны с
Не, я лишь хочу показать более детальнее процесс взаимодействия с мёртвым нпс.
То, что я писал выше - это одна из наиболее сложных и возможно даже не реализуемых функций.
и мой ответ был исходя из них. :)

Как всегда мысль прилетает после того, как напишу вопрос. Не даром пишут: "jr13san, тебе не надоело самому себе на вопросы отвечать?"
Не зря говорят что "Грамотное описание проблемы содержит половину решения этой проблемы" *flowers*
 

Jr13San


Модостроитель
Регистрация
1 Апр 2010
Сообщения
449
Благодарности
266
Баллы
230
Есть другая проблема, мб даже никто об этом и не знает...
Попробую изложить понятно.

У меня есть функция, которая выводит сообщение с номером, через который можно обращаться, в данном случае к предмету.
Код:
func void GiveInst(var C_ITEM itm)
{
Print(IntToString(Hlp_GetInstanceID(itm)));
};


Так я вызываю функцию:
GiveInst(ItRw_Arrow);

Рассмотрим пример со стрелой, как мульти-объектом. Мульти - т.е. собирается в кучку.

1) Вызываю функцию GiveInst(ItRw_Arrow) с отсутствием инициализции стрелы. Т.е. стрела в мир не вставлена.
Функция возвращает "-1". Это правильно.
2) Вставляю в мир 1 стрелу. Кладу в инвентарь. Вызываю функцию. Фнкция возвращает "7001". Это правильно. Это тот порядковый номер, через который можно обратиться к этой стреле.
3) Вставляю ещё 1 стрелу в инвентарь. Их становится 2. Вызываю функцию. Функция возвращает "-1". Вот это не правильно. Почему она так обработала информацию?
Потому что стрел кучка и ссылки на кучку нету?
А почему тогда функция Hlp_GetInstanceID(ItRw_Arrow) возвратит ссылку на эту кучку?


Jr13San,
Ссылка на итемку существует на одну штуку в мире. Именно поэтому нельзя дважды применить команду Wld_RemoveItem
Я не могу поверить и уступить тоже...
Ссылки на кучку нет(пока что). А вот кол-во стрел в кучке можно узнать. Поэтому я и немного ошибся с Hlp_GetInstanceID(ItRw_Arrow). Она тоже не может возвратить ссылку на кучку.
 

redleha


Модостроитель
Регистрация
26 Фев 2008
Сообщения
735
Благодарности
665
Баллы
245
Jr13San,
Ссылка на итемку существует на одну штуку в мире. Именно поэтому нельзя дважды применить команду Wld_RemoveItem
 

Dimmell

Участник форума
Регистрация
23 Ноя 2008
Сообщения
2.899
Благодарности
111
Баллы
285
Jr13San,
сразу и куча ошибок :)
Функция int Hlp_GetInstanceID (c_item item); - получить ID номер предмета по ссылке на класс item., а не на int instanceName. А ты пытаешься использовать имя инстанции. :)
В игровом мире одна инстанция, но если много предметов одной инстанции - ID у каждого предмета свой. У меня в заточке оружия - точится один предмет, параметры его меняются, если он экипирован - он в отдельном слоте инвентаря, если он снят и в инвентаре есть предметы этой инстанции - они все ложатся в один слот. При обратной экипировке из этих предметов экипируется предмет с лучшими параметрами (т.е. заточенный). Это инфа к размышлению. :)
ЗЫ. Сразу за все хвататься - ничего толком не закончить. :)
Разобрался бы хоть с подсветкой трупа без лута.
 
Сверху Снизу