|
|
25.09.2007, 18:24
|
#1801
|
|
|
|
|
A.G.F.C.
Регистрация: 04.09.2006
Сообщений: 20
|
|
|
|
|
|
Re: М: Скриптинг в Готике
2DimonKDF [FC]:
Получилось. Спасибо. А где находится стартовая точка Гг?
|
Не совсем понял что такое стартовая точка ? Если имеется ввиду начало игры куда вставляется Гг, то нужно лезть в спейсер и смотреть в зене
, там будет установлен специфичный триггер с большой стрелочкой, вот он и есть стартовый... Названия его не сейчас не помню, но при нажатии на него оно появится и ты его ни с чем не спутаешь. Вот именно его и нужно ставить туда, куда ты хочешь прописать своего Гг, ну и естественно настроить сам триггер как нуна. :))
|
|
|
26.09.2007, 19:58
|
#1805
|
|
|
|
|
A.G.F.C.
Регистрация: 04.09.2006
Сообщений: 20
|
|
|
|
|
|
Re: М: Скриптинг в Готике
Цитата:
Сообщение от SMErtNIK link=board=gothic&t=1105030050&start=3756400#37564 10 date=09/26/07, в 00:05:34
Скажите, а в каком файле находятся скрипты отвечающие за отображение диалога? (Именно фраз, которые сопровождаются звуком). А то у меня в моде почему-то вдруг прекратились отображаться фразы :(. Причём это произошло и с новыми диалогами, и со старыми, которые до этого нормально работали :(... Я уже запарился искать причину :(.
|
Если ты имеешь ввиду субтитры, то смотри настройки в ИНИ-файле. В противном случае ты что-то накосячил в скриптах. *;D Распиши что делал и как, а там видно будет может и причина найдется. ;)
|
|
|
26.09.2007, 21:55
|
#1806
|
|
Re: М: Скриптинг в Готике
Вот ИНИ файл.Не знаю что там с ним не впорядке...
Cпойлер(щелкните, чтобы прочесть):
[INFO] Title= Некроманты Version=0.1 Author=SMErtNIK Webpage=http://magic-team.net.ru
Description={\rtf1\ansi\ansicpg1251\pard\qc\lang10 31\ \par\par\par\par\par\par\par\par }
Icon=0
[FILES]
VDF=Necromancers.mod
Game=Content\Gothic FightAI=Content\Fight Menu=System\Menu Camera=System\Camera Music=System\Music SoundEffects=System\SFX ParticleEffects=System\ParticleFX VisualEffects=System\VisualFX
OutputUnits=OU
[SETTINGS]
World=minimod_world_2.zen
Player=PC_Hero
[OPTIONS]
show_Info=0 show_InfoX=800 show_InfoY=7200
show_Version=0 show_VersionX=6500 show_VersionY=7200
show_Focus=1 show_FocusItm=1 show_FocusMob=1 show_FocusNpc=1 show_FocusBar=1
force_Subtitles=1
[OVERRIDES] INTERNAL.extendedMenu=1
И пожалуй выложу пару диалогов, один который о этого работал, и один который так и не заработал.
Cпойлер(щелкните, чтобы прочесть):
instance DIA_Vendigo_EXIT(C_INFO)
{ npc = none_999_Vendigo; nr = 999; condition = DIA_Vendigo_EXIT_Condition; information = DIA_Vendigo_EXIT_Info; permanent = true; description = "Прекратить разговор"; };
func int DIA_Vendigo_EXIT_Condition()
{ return TRUE; };
func void DIA_Vendigo_EXIT_Info()
{ AI_StopProcessInfos(self); };
instance DIA_Vendigo_HELLO(C_INFO) { npc = none_999_Vendigo; nr = 1; condition = DIA_Vendigo_HELLO_Condition; information = DIA_Vendigo_HELLO_Info; Permanent = false; Description = "Привет! Что забыл наемник в этом гиблом месте?"; };
func int DIA_Vendigo_HELLO_Condition() { return TRUE; };
func int DIA_Vendigo_HELLO_Info() { AI_Output(other, self, "DIA_Vendigo_HALLO_03_00"); // Привет! Что забыл наемник в этом гиблом месте? AI_Output(self,other,"DIA_Vendigo_HALLO_03_01"); // Здравствуй. Я жил здесь когда-то... Ai_Output(self,other,"DIA_Vendigo_HALLO_03_02"); // Это было до разупокоения погостов и нашествия мертвяков... AI_Output(self,other,"DIA_Vendigo_HALLO_03_03"); // Сейчас я пришел сюда чтоб подарить моим предкам покой, которого они лишились.. AI_Output(other, self, "DIA_Vendigo_HALLO_03_04");//А где эти самые "предки", и много их? AI_Output(self,other, "DIA_Vendigo_HALLO_03_05"); //К сожалению их у меня много... И все они превратились в злобных скелетов и зомби... В бездушных мертвяков... return TRUE; };
Cпойлер(щелкните, чтобы прочесть):
instance DIA_Lodochnik_EXIT (C_Info) { npc = none_2004_Lodochnik; nr = 999; condition = DIA_Lodochnik_EXIT_Condition; information = DIA_Lodochnik_EXIT_Info; permanent = true; description = "Прекратить разговор"; };
func int DIA_Lodochnik_EXIT_Condition()
{ return TRUE; };
func void DIA_Lodochnik_EXIT_Info()
{ AI_StopProcessInfos(self); };
instance DIA_Lodochnik_HELLO(C_INFO) { npc = none_2004_Lodochnik; condition = DIA_Lodochnik_HELLO_Condition; information = DIA_Lodochnik_HELLO_Info; Permanent = false; important = TRUE ; };
func int DIA_Lodochnik_HELLO_Condition() { return TRUE; };
func int DIA_Lodochnik_HELLO_Info() { AI_Output(self,other,"DIA_Lodochnik_HELLO_04_01") ;// Приплыли уважаемый маг, вот тот самый остров на который вы так хотели попасть. AI_Output(self,other,"DIA_Lodochnik_HELLO_04_02") ;// Думаю около вон того костра ещё есть кто-то живой. Ваши вещи я положил здесь, на причале. AI_Output(self,other,"DIA_Lodochnik_HELLO_04_03") ;// Не углубляйтесь сильно в лес, думаю там куча нежити, и не простых скелетов-крестьян. AI_Output(self,other,"DIA_Lodochnik_HELLO_04_04") ;// Если захотите уплыть обратно к вашему кораблю, то я буду ждать вас здесь, сразу садитесь в лодку, без разговоров. AI_Output(other,Self,"DIA_Lodochnik_HELLO_15_05") ;// Спасибо за помощь, будь осторожен. return TRUE; };
Порядок действий?.. Да я особо не запоминал... писал скрипт - компилировал, проверя на работоспособность, и т.д.
|
|
|
27.09.2007, 01:51
|
#1807
|
|
|
|
|
A.G.F.C.
Регистрация: 04.09.2006
Сообщений: 20
|
|
|
|
|
|
Re: М: Скриптинг в Готике
2SMErtNIK: Мда... с твоими скриптами все понятно. *;D Инишка нормальная вроде.. А вот в скриптах много багов, вот его примерчик:
Cпойлер(щелкните, чтобы прочесть):
func int DIA_Lodochnik_HELLO_Info() { * AI_Output(self,other,"DIA_Lodochnik_HELLO_04_01");// Приплыли уважаемый маг, вот тот самый остров на который вы так хотели попасть. * AI_Output(self,other,"DIA_Lodochnik_HELLO_04_02");// Думаю около вон того костра ещё есть кто-то живой. Ваши вещи я положил здесь, на причале. * AI_Output(self,other,"DIA_Lodochnik_HELLO_04_03");// Не углубляйтесь сильно в лес, думаю там куча нежити, и не простых скелетов-крестьян. * AI_Output(self,other,"DIA_Lodochnik_HELLO_04_04");// Если захотите уплыть обратно к вашему кораблю, то я буду ждать вас здесь, сразу садитесь в лодку, без разговоров. * AI_Output(other,Self,"DIA_Lodochnik_HELLO_15_05");// Спасибо за помощь, будь осторожен. return TRUE; };
Функция Info в диалогах не может быть типом int, только void.
Возможно именно в этом твои баги... это то что встретилось на первый взгляд... В общем, почитай тотуры и не спеши с написанием скриптов, тебе нужно учить построение функций для начала, и только потом пробывать что-то писать. Именно в этом у тебя больше всего багов. *;)
|
|
|
27.09.2007, 15:43
|
#1808
|
|
Re: М: Скриптинг в Готике
правлю скрипты в первой готике. вот пример, на него ругается сурсер:
Cпойлер(щелкните, чтобы прочесть):
func int ZS_AssessQuietSound() { * * *PrintDebugNpc (PD_ZS_FRAME, "ZS_AssessQuietSound"); * * *C_ZSInit (); * * *if (self.guild == GIL_MEATBUG) * * *{ * * * * * *AI_ContinueRoutine (self); * * * * * *return 0; * * *}; * * *Npc_PercEnable (self, PERC_ASSESSDAMAGE, ZS_ReactToDamage); * * *Npc_PercEnable (self, PERC_ASSESSMAGIC, B_AssessMagic); * * *Npc_PercEnable (self, PERC_ASSESSSURPRISE, ZS_AssessSurprise); * * *Npc_PercEnable (self, PERC_ASSESSENEMY, B_AssessEnemy); * * *Npc_PercEnable (self, PERC_ASSESSFIGHTER, B_AssessFighter); * * *Npc_PercEnable (self, PERC_ASSESSTHREAT, B_AssessFighter); * * *Npc_PercEnable (self, PERC_ASSESSWARN, B_AssessWarn); * * *Npc_PercEnable (self, PERC_ASSESSMURDER, ZS_AssessMurder); * * *Npc_PercEnable (self, PERC_ASSESSDEFEAT, ZS_AssessDefeat); * * *Npc_PercEnable (self, PERC_ASSESSFIGHTSOUND, B_AssessFightSound); * * *Npc_PercEnable (self, PERC_CATCHTHIEF, ZS_CatchThief); * * *Npc_PercEnable (self, PERC_ASSESSTHEFT, B_AssessTheft); * * *Npc_PercEnable (self, PERC_ASSESSTALK, B_RefuseTalk); * * *Npc_PercEnable (self, PERC_ASSESSENTERROOM, B_AssessEnterRoom); * * *Npc_PercEnable (self, PERC_ASSESSUSEMOB, B_AssessUseMob); * * *AI_TurnToNPC (self, other); };
эта ф-ия входит в обработчик состояния, как я понял. нашел описание от Vam-а:
Cпойлер(щелкните, чтобы прочесть):
2. Есть обработчики состояний людей и монстров, которые состоят из трех функций, вход в состояние - функция должна иметь тип void и ничего не возвращать, цикл состояния - функция должна иметь тип int и возвращать LOOP_END или LOOP_CONTINUE, выход из состояния - функция должна иметь тип void и ничего не возвращать.
из него следует, что вход в состояние должен быть void. на это указывает и формат записи вызывающей ф-ии: AI_StartState (self, ZS_AssessQuietSound, 0, "");однако здесь есть return 0. вот и вопрос, что вернуть в этом случае? или return без нуля сделать? Добавление от 09/27/07, в 04:11:26
еще. практически все ф-ии func int *_trigger не имеют вызовов в скриптах, но такие названия присутствуют в zen файлах. требуют ли они чего-нибудь в возврате? Добавление от 09/27/07, в 16:03:51
сам себе отвечаю. убрал 0 из ретурна по аналогии с другими скриптами, которые есть void, но в них предусмотрен досрочный выход. в func int *_trigger добавил в конец retrun 0. проверил путем создания в меню аналогичной ф-ии, каких либо ошибок не произошло. в итоге добил таки редактирование скриптов от снежковской версии с целью безошибочной компиляции. руководствовался следующим (сорри, что без авторства):
Cпойлер(щелкните, чтобы прочесть):
1. Внутри функции есть return'ы, а при выходе из нее отсутствует -> нужно записать соответствующий return со значением. 2. Есть обработчики состояний людей и монстров, которые состоят из трех функций, вход в состояние - функция должна иметь тип void и ничего не возвращать, цикл состояния - функция должна иметь тип int и возвращать LOOP_END или LOOP_CONTINUE, выход из состояния - функция должна иметь тип void и ничего не возвращать. 3. Функция Info в диалогах не может быть типом int, только void. 4. func int ххх_condition() - должна возвращать значение, а функция func void ххх_info() - должна иметь тип void и ничего не возвращать. 5. уж совсем откровенные ляпы правились без всяких правил :)
все правки отмечал коментариями, начинающимися с "//hhr". далее несколько вариантов: int->void - смена типа ф-ии comment - закоментаривание последнего блока elseadd - обычно это добавленный return 0;вот версия, которая компилируется без ошибок (однако имеется более 50 "вниманий"): ссылкаа вот вариант, в котором отредактировал все предупреждения ("внимания"): ссылкапо ссылка лежат каталоги с проектом для сурсера, только скрипты от gothic.dat&ou.bin концерт не внедрялся, только правка снежковской версии.
|
|
|
28.09.2007, 01:02
|
#1809
|
|
Re: М: Скриптинг в Готике
2HikeR:
Глянул тему, Декомпилятора, в которой ты все же неудержался наскриптить, (а насколько было бы удобно сразу цитировать из ЭТОЙ темы) и собственно думаю, что такой метод "ухода от ретурна" может привести к ошибкам в игре, т.к. функция ЯВНО возвращает ТОЛЬКО "return TRUE;", другого варианта НЕТ вообще.
func int C_NpcIsOrc(var C_Npc slf) { PrintDebugNpc (PD_ZS_DETAIL, "C_NpcIsOrc"); if (slf.guild > GIL_SEPERATOR_ORC) { PrintDebugNpc (PD_ZS_DETAIL, "...true"); return TRUE; }; //else //{ PrintDebugNpc (PD_ZS_DETAIL, "...false"); return FALSE; //}; };
ИМХО, более правильный метод исправления был бы таким:
func int C_NpcIsOrc(var C_Npc slf) { PrintDebugNpc (PD_ZS_DETAIL, "C_NpcIsOrc"); if (slf.guild > GIL_SEPERATOR_ORC) { PrintDebugNpc (PD_ZS_DETAIL, "...true"); return TRUE; }; return FALSE; };
Т.к. все же ЯВНО возвращает "return FALSE;", в случае ОТРИЦАТЕЛЬНОЙ проверки УСЛОВИЯ. Собственно я уже показывал подобный пример в ЭТОЙ теме (Ответ #1780)
|
|
|
28.09.2007, 01:15
|
#1810
|
|
Re: М: Скриптинг в Готике
2Ukur: если убрать из верхней ф-ии закоментированные строки, то получится точь в точь нижняя ф-ия. только без строки PrintDebugNpc (PD_ZS_DETAIL, "...false");. поэтому я совсем не понимаю приведенный пример :(
ты все же неудержался наскриптить,
|
вообще-то это был пример скрипта, на котором вылезала *ошибка. ошибки постят ведь с примерами, правильно? Добавление от 09/28/07, в 01:16:31
Собственно я уже показывал подобный пример
|
дык с него и взято ;)
|
|
|
28.09.2007, 01:37
|
#1811
|
|
Re: М: Скриптинг в Готике
2HikeR:
В том примере я НЕ комментил ретурны. 2HikeR:
только без строки PrintDebugNpc (PD_ZS_DETAIL, "...false");
|
Эту строку я просто забыл вписать, т.к. она не несет никакой скриптовой нагрузки в процесс игры и используется только для отладочных целей в режиме разработчика *(Тяжело все же углядеть все мелочи, когда пытаешься сделать цитату не с темы для обсуждения скриптов "Декомпилятора"). Ага, все заметил! Ты закооментил только скобки, но не сам Ретурн, ну что-же, неплохо. P.S. Поздравляю с устным предом, далее пойдут меры посерьезнее :)
|
|
|
28.09.2007, 02:15
|
#1813
|
|
Re: М: Скриптинг в Готике
2HikeR:
какие скрипты активируются во время боя? где покопать нужно?
|
ищи функцию связанную с восприятием повреждения PERC_ASSESSDAMAGE
|
|
|
28.09.2007, 03:58
|
#1814
|
|
Re: М: Скриптинг в Готике
ищи функцию связанную с восприятием повреждения PERC_ASSESSDAMAGE
|
посмотрел, я там и не лазил почти. вернул обратно правки, ставил оригинальные скрипты, все равно переодические вылеты. переключился в полноэкранный режим - почти полчаса без вылетов... но попутно нашел у себя неточность, в файле ZS_MM_Master. тем 12-ти скачавшим по ссылкам из поста 1805 наверное нужно поправить:
Cпойлер(щелкните, чтобы прочесть):
func [strike]int[/strike] void B_MM_DeSynchronize() { * * *var int msec; * * *PrintDebugNpc (PD_MST_FRAME, "B_MM_DeSynchronize"); * * *msec = Hlp_Random (1000); * * *AI_Waitms (self, msec); * * [strike]return 0;[/strike] }; так как все вызовы из скриптов идут без присвоения.
Добавление от 09/28/07, в 04:18:12
кстати, по расшифровке сообщений в zLog-е здесь можно спросить?
|
|
|
28.09.2007, 20:29
|
#1816
|
|
Re: М: Скриптинг в Готике
2360:
!(Npc_KnowsInfo(hero,GRD_200_Thorus_WANNABEMAGE)
|
А какая версия декомпилера? ;) Там в старых ошибка была - неправильно приоритеты операций разбирались - как с таким результатом - ! выезжал за скобки.
|
|
|
29.09.2007, 03:34
|
#1817
|
|
Re: М: Скриптинг в Готике
если это файл Story\MISSIONS\DIA_Kdf_402_Corristo.d, то последним сурсером получается второй вариант. а вот как это выглядит в оригинале:
Cпойлер(щелкните, чтобы прочесть):
FUNC int *Info_Corristo_Intruder_Condition() { * * *if * * *Npc_IsInState(self,ZS_Talk) * * *&& * * *( (!Npc_KnowsInfo(hero,GRD_200_Thorus_WANNABEMAGE)) && (CorKalom_BringMCQBalls != LOG_SUCCESS) ) * * *{ * * * * * *return 1; * * *}; };
Добавление от 09/29/07, в 01:29:07
в файле ZS_MM_Master.d есть странная функция:
Cпойлер(щелкните, чтобы прочесть):
func void B_MM_AssessEnemy_Sleep() { * *PrintDebugNpc (PD_MST_FRAME, "B_MM_AssessEnemy_Sleep"); * * * * *if (C_BodyStateContains(self,BS_LIE)) * * *{ * * * * * *if (Npc_GetDistToNpc(self,other)<200) * * * * * *{ * * * * * * * * *B_MM_AssessEnemy(); * * * * * *}; * * *} * * *else * * *{ * * * * * *B_MM_AssessEnemy(); * * *}; };
она всегда возвращает одно и тоже значение. в таком виде она и в русской и в немецкой версиях, а также в скриптах из MDK. вероятно ее можно сократить до вида
Cпойлер(щелкните, чтобы прочесть):
func void B_MM_AssessEnemy_Sleep() { * *PrintDebugNpc (PD_MST_FRAME, "B_MM_AssessEnemy_Sleep"); * *B_MM_AssessEnemy(); };
в таком случае. ну и вопрос, что хотели разрабы вложить в нее изначально, есть мысли? Добавление от 09/29/07, в 03:54:54
попробовал в главном меню использовать ф-ии func void Print(var string text); func int PrintScreen(var string text, var int x, var int y, var string font, var int timeSec); сурсер поругался, спейсер тоже. получается, в главном меню эти ф-ии еще не проинициализированы? можно ли ещё как-то вывести текстовую строку в главном меню?
|
|
|
29.09.2007, 09:58
|
#1818
|
|
Re: М: Скриптинг в Готике
2HikeR:
она всегда возвращает одно и тоже значение. в таком виде она и в русской и в немецкой версиях, а также в скриптах из MDK. вероятно ее можно сократить до вида
|
Во-первых: Данная функция объявлена с типом void, следовательно ничего возвращать она не может. Во-вторых: Приведенное тобой сокращение в корне неверно, т.к. в твоём случае функия B_MM_AssessEnemy(); будет вызываться всегда, а в оригинале она не будет вызвана при условии - если self лежит и расстояние от self до other >= 200 метрам. Если хочешь оптимизировать эту функцию, то можно записать так: [pre]func void B_MM_AssessEnemy_Sleep() { * PrintDebugNpc (PD_MST_FRAME, "B_MM_AssessEnemy_Sleep"); * if(!C_BodyStateContains(self, BS_LIE) || (Npc_GetDistToNpc(self, other) < 200)) * { * * *B_MM_AssessEnemy(); * }; };[/pre]
попробовал в главном меню использовать ф-ии
|
В модуле Menu можно использовать только функции, которые указаны в файле Int_FuncMenu_*.d программы GS v3.14, другие функции движок не поддерживает.
можно ли ещё как-то вывести текстовую строку в главном меню?
|
Можно, создав item элемент меню и вставив его в нужное место.
то последним сурсером получается второй вариант. а вот как это выглядит в оригинале:
|
Оригинал и строки, созданные декомпилятором версии 3.14 логически не отличаются друг от друга, и следовательно - работать будут одинаково.
|
|
|
29.09.2007, 10:14
|
#1819
|
|
Re: М: Скриптинг в Готике
2HikeR:
попробовал в главном меню использовать ф-ии func void Print(var string text); func int PrintScreen(var string text, var int x, var int y, var string font, var int timeSec); сурсер поругался, спейсер тоже.
|
Скрипты Gothic.dat и Menu.dat имеют различное назначение для игры и отличаются набором функций. 2HikeR:
получается, в главном меню эти ф-ии еще не проинициализированы?
|
Многие функции Gothic.dat вообще там не поддерживаются движком игры. 2HikeR:
можно ли ещё как-то вывести текстовую строку в главном меню?
|
Кратковременно как PrintScreen или Print врятли, а вот изменять меню игры, добавляя в него различные новые пункты меню, или текстовые описания к ним легко.
|
|
|
29.09.2007, 12:16
|
#1821
|
|
Re: М: Скриптинг в Готике
2Vam:
func void B_MM_AssessEnemy_Sleep() { * * *PrintDebugNpc (PD_MST_FRAME, "B_MM_AssessEnemy_Sleep"); * * *if(!C_BodyStateContains(self, BS_LIE) || (Npc_GetDistToNpc(self, other) < 200)) * * *{ * * * * * *B_MM_AssessEnemy(); * * *}; };
|
Вариант оптимизации НЕ верен, в этом случае вызов функции B_MM_AssessEnemy(); выполняется ВСЕГДА при соблюдении одного из двух условий. В оригинальном же варианте возможно НЕВЫПОЛНЕНИЕ вызова функции: B_MM_AssessEnemy(); 2HikeR:
func void B_MM_AssessEnemy_Sleep() { * PrintDebugNpc (PD_MST_FRAME, "B_MM_AssessEnemy_Sleep"); * * * if (C_BodyStateContains(self,BS_LIE)) * * { * * * * * if (Npc_GetDistToNpc(self,other)<200) * * * * * { * * * * * * * * B_MM_AssessEnemy(); * * * * * }; * * * * * //Если не выполняется вышеописанное условие, в этом случае B_MM_AssessEnemy(); НЕ вызывается, хотя и было выполнено первое условие.
* * } * * else * * { * * * * * B_MM_AssessEnemy(); * * }; };
|
И ИМХО, стоит оставить функцию в первозданном виде.
|
|
|
29.09.2007, 15:51
|
#1822
|
|
Re: М: Скриптинг в Готике
2Vam:
Во-первых: Данная функция объявлена с типом void, следовательно ничего возвращать она не может.
|
мда, описка. имел в виду не "возвращение", а "выполнение".
в оригинале она не будет вызвана при условии - если self лежит и расстояние от self до other >= 200 метрам.
|
действительно. нельзя ночью думать, в который раз убеждаюсь ;) 2Ukur:
В оригинальном же варианте возможно НЕВЫПОЛНЕНИЕ вызова функции: B_MM_AssessEnemy();
|
тогда уж так: func void B_MM_AssessEnemy_Sleep() { * PrintDebugNpc (PD_MST_FRAME, "B_MM_AssessEnemy_Sleep"); * * * if (C_BodyStateContains(self,BS_LIE) && Npc_GetDistToNpc(self,other)<200)) * * || !C_BodyStateContains(self,BS_LIE) * * { * * * * * B_MM_AssessEnemy(); * * }; };по-крайней мере для меня это более наглядно, чем оригинальный вариант. Добавление от 09/29/07, в 16:01:51
кстати, подобные оптимизации хоть как-то могут повлиять на скорость выполнения? или откомпилированный результат будет одинаков в любом случае, и овчинка выделки не стоит?
|
|
|
29.09.2007, 16:21
|
#1823
|
|
Re: М: Скриптинг в Готике
2Ukur:
в этом случае вызов функции B_MM_AssessEnemy(); выполняется ВСЕГДА при соблюдении одного из двух условий.
|
Правильно, давай порассуждаем, (хотя, если использовать правила булевой алгебры, то и рассуждать незачем): для простоты понимания первое условие примем за "аа", а второе условие за "bb", следовательно будут справедливы следующие выражения, которые приведут к вызову функции B_MM_AssessEnemy();: 1). "аа" && "bb" (первая ветка if -> if) 2). "!aa" (вторая ветка, else) обобщая их получаем ("аа" && "bb") || "!aa" Условие же не вызова функции проще и может быть записано так: "аа" && "!bb", следовательно по закону дуальности булевой алгебры условие вызова функции можно записать так: "!аа" || "bb", что я и сделал в предыдущем посте. Булева алгебра - интересная вещь - на данную функцию можно написать ещё несколько выражений *и все они будут справедливы и правильно работать, но только одно из них, а может быть и несколько, будет(ут) оптимальным(и), а какое на первый взгляд сказать трудно, только построив таблицу Вейче можно сказать это с уверенностью. Добавление от 09/29/07, в 16:29:32 2HikeR:
кстати, подобные оптимизации хоть как-то могут повлиять на скорость выполнения? или откомпилированный результат будет одинаков в любом случае, и овчинка выделки не стоит?
|
Всё зависит от того, как выполняется код, конкретно по Готикам (движок их я изучил почти полностью) можно сказать, что при оптимизации: 1. Уменьшится размер стека (он равен 2048), т.е. движок при выполнении кода все переменные действия с ними и промежуточные результаты записывает в стек. Если стек закончится, то получим вылет игры, но не узнаем по какой причине он произошел. Следовательно, лучше экономить место в стеке. 2. Быстродействие - если в функции будет выполняться меньше проверок, то это лучше. Если вернуться к разбираемой функции, то можно записать условие так "bb" || "!аа", по правилам булевой алгебры это идентично, но относительно быстродействия это совсем разные вещи: какое условие чаще встречается? "!аа" - self не лежит, или "bb" - расстояние между self и other < 200 метров. Для оптимизации быстродействия при операции || первым надо ставить выражение, которое реже бывает истинным, следовательно второе выражение выполняться не будет и быстродействие повысится. Добавление от 09/29/07, в 16:40:59
Извиняюсь за ошибку (но почему-то добавленное сообщение нельзя редактировать *:( ): предыдущий абзац следует читать так "... первым надо ставить выражение, которое реже бывает ложным ..."
|
|
|
29.09.2007, 17:30
|
#1824
|
|
Re: М: Скриптинг в Готике
2Vam:
Булева алгебра - интересная вещь
|
Вещь конечно интересная, но тогда я попробую предложить свои наблюдения по работе оригинальной и функции твоего варианта... func void B_MM_AssessEnemy_Sleep() { *PrintDebugNpc (PD_MST_FRAME, "B_MM_AssessEnemy_Sleep"); * * *if (C_BodyStateContains(self,BS_LIE)) \\ 1. Вариант * *{ * * * * *if (Npc_GetDistToNpc(self,other)<200) * * * * *{ * * * * * * * *B_MM_AssessEnemy(); * * * * *}; * *} * *else \\ 2. Вариант * *{ * * * * *B_MM_AssessEnemy(); * *}; }; 1 Вариант. Для того чтобы срботала проерка дистанции от игрока, self при этом должен ЛЕЖАТЬ. в этом случае сработает вызов B_MM_AssessEnemy(); 2 Вариант. B_MM_AssessEnemy(); срабатывает при невыполнении первого условия 1 Варианта. func void B_MM_AssessEnemy_Sleep() { * * PrintDebugNpc (PD_MST_FRAME, "B_MM_AssessEnemy_Sleep"); * * if (!C_BodyStateContains(self, BS_LIE) || (Npc_GetDistToNpc(self, other) < 200)) * * { * * * * * B_MM_AssessEnemy(); * * }; }; Функция срабатывает если сработала проверка дистанции от игрока или self НЕ ЛЕЖИТ.Собственно различия. В оригинальном варианте: ВЫЗОВ B_MM_AssessEnemy(); 1 Вариант для ЛЕЖАЧЕГО. возможен ТОЛЬКО при условии проверки дистанции от игрока или 2 Вариант для НЕ ЛЕЖАЧЕГОВ твоем варианте Вызов функции возможен и для НЕ ЛЕЖАЧЕГО и при проверке дистанции от игрокаА где же обязательное ЛЕЖАНИЕ, которое должно быть выполнено вместе с проверкой дистанции от игрока? Алгебра алгеброй, а неувязочка на лицо! :) Вот вариант 2HikeR: лишен этой неувязки!
func void B_MM_AssessEnemy_Sleep() { *PrintDebugNpc (PD_MST_FRAME, "B_MM_AssessEnemy_Sleep"); * * *if (C_BodyStateContains(self,BS_LIE) && Npc_GetDistToNpc(self,other)<200)) * *|| !C_BodyStateContains(self,BS_LIE) * *{ * * * * *B_MM_AssessEnemy(); * *}; };
|
Проверяются все условия, как это было в оригинальной функции. P.S. Юзал булевую алгебру? :)
|
|
|
29.09.2007, 19:27
|
#1825
|
|
Re: М: Скриптинг в Готике
юзал всевозможные варианты. имеем 4 варианта входных условий. сведем все в табличку, 1 - условие выполняется, 0 - не выполняется: [table] [tr][td][/td][td]bb[/td][td]!bb[/td][/tr] [tr][td]aa[/td][td]1[/td][td]0[/td][/tr] [tr][td]!aa[/td][td]1[/td][td]1[/td][/tr] [/table] причем, эта табличка справедлива для обоих вариантов. как для (aa && bb) || !aa, так и для (!aa || bb)вот это пока непонятно почему. Добавление от 09/29/07, в 19:22:31
расшифровка: aa - лежит, !aa - НЕ лежит bb - близко, !bb - далеко. Добавление от 09/29/07, в 19:44:37
в оригинале B_MM_AssessEnemy(); НЕ выполняется только в одном случае - self лежит и он далеко. при любых других комбинациях B_MM_AssessEnemy(); выполняется: лежит далеко - нет лежит близко - да НЕ лежит далеко - да НЕ лежит близко - да для выражения (!aa || bb) НЕвыполнение условия приводит к тому же варианту, просто ф-ию тогда нужно записать несколько иначе: if !( !aa || bb) {B_MM_AssessEnemy();};чуствую, надо подучиться ;) Добавление от 09/29/07, в 19:47:28 2Vam:
первым надо ставить выражение, которое реже бывает ложным ...
|
я добавил два PrintDebug() на обе проверки, пограю, посмотрю, что в логе чаще встречается.
|
|
|
29.09.2007, 20:12
|
#1826
|
|
Re: М: Скриптинг в Готике
2HikeR:
юзал всевозможные варианты
|
Таблицу Вейче составил правильно - похвально.
просто ф-ию тогда нужно записать несколько иначе: if !( !aa || bb) {B_MM_AssessEnemy();};
|
А вот с вычислением выражения ошибочка, поясняю: Оптимизируем по 1, т.к. их в таблице больше, первое выражение (1ый столбик) - bb, аа сокращаются второе выражение (2ая строка) - !аа, bb сокращаются далее, т.к. мы делаем по 1, то между выражениями ставим || (если бы по нулям, то &&) в итоге получаем для истиного выражения (вызов функции) - !aa || bb, откуда у тебя взялось общее отрицание непонятно, оно справедливо для невызова функции. А в общем неплохо. ;)
|
|
|
29.09.2007, 21:35
|
#1828
|
|
Re: М: Скриптинг в Готике
2Владай:
Ну так вот, скажите плиз как и где прописать в скриптах звуки, с ним связанные (ну там то что он кричит при атаке, или когда заметил кого-нибудь
|
Т.е. стандартные реплики, которые уже есть в скриптах... Для этого желательно для НПЦ указать НОВЫЙ номер собственного голоса "voice", а затем по аналогии прописать НОВЫЙ номер голоса в \Story\Svm.d Изначально в Svm.d прописано 20 голосов 15 - голос ГГ 16 и 17 помоему женские. 18 - голос Орков (пустой) 19 - голос Ищущих (мало фраз) Можешь попробовать дополнить голоса 18 и 19 и заюзать для своего НПЦ, или попробовать добавить новый, но я не знаю есть ли ограничения на количество голосов в КЛАССЕ для НПЦ Далее все фразы будут применяться к НПЦ, согласно фразам прописанным для номера голоса в Svm.d
|
|
|
30.09.2007, 10:27
|
#1830
|
|
Re: М: Скриптинг в Готике
2HikeR:
этих анимаций нет в моем варианте, может они есть у кого еще? если нет, то может закоментировать вообще эти строки?
|
Теперь в теме Скриптинга переключился на Анимацию? (см. локальные правила темы в шапке) :) Вообще-то есть еще тема про Модостроение в Готике, но т.к. тебе дали совет не обращать внимания на подобные замечания со стороны других жителей форума, продолжаем обсуждение здесь. А поподробнее можно расписать, какие действия (компиляция\декомпиляция\конвертирование) совершаешь и над чем (формат модели\анимации, расширение файла)?
|
|
|
30.09.2007, 20:34
|
#1832
|
|
Re: М: Скриптинг в Готике
2Владай:
(Ну или сделал водяного голема, а где прописать землетрясение при ходьбе?!)
|
Ну эт уже другая тема... Ближе к Модостроению.. Попробую объяснить о звуках ходьбы на примере Каменного Голема. Вообщем звуки ходьбы прописываются в некомпилированном скрипте анимации Golem.mds, который нужно затем перекомпилировать. Некомпилированный вариант можно добыть из пакета G2MDK, либо воспользовавшись ГотикСорсером декомпилировать golem.msb (для Г2а). В Г1 скрипты анимации используются сразу в некомпилированном виде *.mds Пример строки из файла: Golem.mds *eventSFX (22 "GOL_STEPBOOM" Все переменные звуков для применения в скриптах анимации либо для... 2Владай:
ну как например, луркера: ведь он тоже издает звуки, так где ж эти звуки прописать кроме как Svm.d?
|
Прописываются в SFX.DAT, исходные скрипты которого также можно добыть из G2MDK, либо Декомпилятором.. После получения исходников звуки монстров и окружения ищи в SfxInst.d, переменные для фраз людей в SfxInstSpeech.d
|
|
|
01.10.2007, 05:13
|
#1833
|
|
Re: М: Скриптинг в Готике
2Ukur:
Теперь в теме Скриптинга переключился на Анимацию?
|
1.расшифровываю: как и где поправить/добавить скрипты, чтобы не вызывались отсутствующие анимации, и соответственно не забивался лог? 2. можно ли регулировать дальность действя оружия? для меча на полметра, например, увеличить дистанцию поражения. 3. при передвижении ГГ игра динамически вставляет/удаляет НПС-ов в/из мира, видимо для экономии ресурсов. где регулируется расстояние, на котором происходит добавление/удаление? или же это жестко прописано в zen файлахи скриптами не изменяется?
|
|
|
01.10.2007, 05:42
|
#1834
|
|
|
|
|
A.G.F.C.
Регистрация: 04.09.2006
Сообщений: 20
|
|
|
|
|
|
Re: М: Скриптинг в Готике
2HikeR:
1.расшифровываю: как и где поправить/добавить скрипты, чтобы не вызывались отсутствующие анимации, и соответственно не забивался лог?
|
- не совсем понял о какой анимации речь.
2. можно ли регулировать дальность действя оружия? для меча на полметра, например, увеличить дистанцию поражения.
|
- Можно, в инстанции меча ставь значение которое нужно, вот в этот параметр: * * *range = Range_VLKDolch; Либо переменная, либо число на прямую.
3. при передвижении ГГ игра динамически вставляет/удаляет НПС-ов в/из мира, видимо для экономии ресурсов. где регулируется расстояние, на котором происходит добавление/удаление? или же это жестко прописано в zen файлахи скриптами не изменяется?
|
- Регулируется в восприятиях, как Нпс, пропадает из поля видимости Гг он телепортируется на нужный вейпоинт. Но изменение скриптов делу не поможет, так как реализация этого вшито в движок игры а не в зен или скрипты.
|
|
|
01.10.2007, 05:52
|
#1835
|
|
Re: М: Скриптинг в Готике
2HikeR:
1.расшифровываю: как и где поправить/добавить скрипты, чтобы не вызывались отсутствующие анимации, и соответственно не забивался лог?
|
Ох, как вы однако к вопросу прислушиваетесь... Вас спросили, какое действие совершаете при отлове в zSpy вниманий, могу только предположить - обычный запуск игры. Ответ: с этими вниманиями вы скорее всего уже ничего не сделаете, т.к. это внимания на ссылки в файл анимации, который по каким либо причинам не содержит этих анимаций, т.е. был "некорректно" скомпилирован. Возможно ранее предпологалось использование этих анимаций, которые потом посекли - не до конца. Можете попробовать декомпилировать все анимации, вычистить от ненужного хлама и внось закомпилировать - но, ИМХО лишний бред на свою голову :) 2HikeR:
2. можно ли регулировать дальность действя оружия? для меча на полметра, например, увеличить дистанцию поражения.
|
Для каждой боевой единицы ближнего боя в скриптах прописывается радиус воздействия. instance ItMw_1h_Bau_Mace(C_Item) { name = "Schwerer Ast"; mainflag = ITEM_KAT_NF; flags = ITEM_AXE; material = MAT_WOOD; value = Value_BauMace; damageTotal = Damage_BauMace; damagetype = DAM_BLUNT; range = Range_BauMace; cond_atr[2] = ATR_STRENGTH; cond_value[2] = Condition_BauMace; visual = "ItMw_010_1h_Club_01.3DS"; description = name; text[2] = NAME_Damage; count[2] = damageTotal; text[3] = NAME_Str_needed; count[3] = cond_value[2]; text[4] = NAME_OneHanded; text[5] = NAME_Value; count[5] = value; }; 2HikeR:
3. при передвижении ГГ игра динамически вставляет/удаляет НПС-ов в/из мира, видимо для экономии ресурсов. где регулируется расстояние, на котором происходит добавление/удаление? или же это жестко прописано в zen файлахи скриптами не изменяется?
|
Помоему это зашито исключительно в ДВИЖКЕ игры, т.к. на форуме обсуждалось создание мультиплеера и одной из проблем было как раз "упаковка" НПЦ на дальнем расстоянии в "спящий режим".
|
|
|
01.10.2007, 18:25
|
#1836
|
|
Re: М: Скриптинг в Готике
Цитата:
Сообщение от Владай link=board=gothic&t=1105030050&start=3762975#37629 88 date=09/29/07, в 21:21:42
...кричит при атаке, или когда заметил кого-нибудь; ... только не отсылайте меня на поисковик, ведь мне нужен конкретный ответ, а всю тему скриптинга я просто не могу просмотреть...
|
Поиском все равно придется пользоваться ;) "Найти в файлах" Стандартные фразы неписей прописаны в SVM.d
|
|
|
02.10.2007, 21:31
|
#1837
|
|
Re: М: Скриптинг в Готике
жарю мясо - в инвентаре сырое и жареное мясо в двух клетках с указанием количества. изготавляваю мечи из необработанной стали - в инвентаре куча отдельных мечей. также не группируются кирки, поварежки. и у меня и у торговцев инвентарь после продажи мечей забивается, неудобно до жути. можно ли по аналогии с жареным мясом сделать группировку? если да, то где этот "жареный" скрипт? Добавление от 10/02/07, в 21:41:05
на форуме обсуждалось создание мультиплеера и одной из проблем было как раз "упаковка" НПЦ на дальнем расстоянии в "спящий режим".
|
то есть, если сделать нпс-а и сказать ему идти из точки а в точку б, то при отдалении от этого нпс-а он просто "замрет" на месте? или мгновенно переместится в точку назначения? если сопровождать диего в начале игры, то он идет веь путь пешком, однако стоит отвернутся как он появляется уже в лагере, это и есть пример такого поведения?
|
|
|
02.10.2007, 22:56
|
#1838
|
|
|
|
|
A.G.F.C.
Регистрация: 04.09.2006
Сообщений: 20
|
|
|
|
|
|
Re: М: Скриптинг в Готике
2HikeR: Этот жареный скрипт в инстанции предмета, т.е. пример:
Cпойлер(щелкните, чтобы прочесть):
instance ItMi_Pliers(C_Item) { * * *name = "Щипцы"; * * *mainflag = ITEM_KAT_NONE; * * *flags = ITEM_MULTI; * * *value = Value_RuneBlank; * * *visual = "ItMi_Pliers.3DS"; * * *material = MAT_METAL; * * *description = name; * * *text[5] = NAME_Value; * * *count[5] = value; }; Тебе нужно во всех предметах, которые есть в игре прописать в инстанциях эту строчку.: flags = ITEM_MULTI; И они все будут складываться в одну ячейку, естественно в соответствии с инстанцией предмета.
на форуме обсуждалось создание мультиплеера и одной из проблем было как раз "упаковка" НПЦ на дальнем расстоянии в "спящий режим". то есть, если сделать нпс-а и сказать ему идти из точки а в точку б, то при отдалении от этого нпс-а он просто "замрет" на месте? или мгновенно переместится в точку назначения? если сопровождать диего в начале игры, то он идет веь путь пешком, однако стоит отвернутся как он появляется уже в лагере, это и есть пример такого поведения?
|
Примерно так, а именно.: Пока Нпс находится в поле зрения(восприятия Гг), он будет нормально идти куда нужно,или бежать, в зависимости от его распорядка дня. Как только Нпс выйдет из поля восприятия Гг, двиг игры удаляет этого Нпс из мира и вставляет его в то место куда он направлялся по своему распорядку дня или событию.(т.е. конечный вейпоинт). :)
|
|
|
03.10.2007, 02:43
|
#1839
|
|
Re: М: Скриптинг в Готике
2MaGoth:
Тебе нужно во всех предметах, которые есть в игре прописать в инстанциях эту строчку.: flags = ITEM_MULTI;
|
ну, видимо, не во всех ;) руны не имеют такого флага, а свитки - да. до рун я еще не добрался, но полагаю, что много рун бывает редко ;) что делать, если у всего оружия уже есть флаг типа ITEM_AXE или ITEM_SWD? на примере "простого меча", который и создается самостоятельно и был в у меня в кол-ве 10 штук попробовал. заменил вот так: flags = ITEM_SWD + ITEM_MULTI; результат: все такие мечи сгруппировались в одну клетку, но при надевании меча подсвечиваются все 10 штук. при торговле обычно одетое оружие заблокировано от продажи, здесь же можно его продать со всей кучей. в принципе, при покупке более мощного оружия приходится сначала его снять, потом продать. в таком варианте одна лишняя операция опускается. однако ошибочная продажа тоже возможна, поэтому что лучше - как-то сразу не понять.если же убрать флаг ITEM_SWD и оставить только ITEM_MULTI - то в инвентаре меч отображается правильно, группируется, продается и даже выбирается как активное оружие. однако взять в руки его уже нельзя :( вобщем, первый вариант устраивает, но все-таки хочется лучшего. есть ли возможность динамически создавать новые инстанции в процессе игры? теоретически можно было бы при "надевании" оружия (или другого предмета) создать на лету новый его экземпляр с другим именем и убирать один аналогичный предмет из инвентаря. тогда в инвентаре был бы один активный предмет (оружие) и остальное кол-во в другой клетке. во второй готике (если не ошибаюсь) так и сделано. Добавление от 10/03/07, в 02:39:20
Как только Нпс выйдет из поля восприятия Гг, двиг игры удаляет этого Нпс из мира и вставляет его в то место куда он направлялся по своему распорядку дня или событию
|
вставляет когда ГГ все таки подойдет (если подойдет) к конечной точке? или игра смотрит на время и решает, каким должен появится вставленный персонаж (сидеть, стоять, спать)? скажем, выманил я гоблинов из пещеры довольно далеко, выпил "ускорения" пару литров и помчался к ним в пещеру сундуки вскрывать. по выходу из пещеры они будут меня уже ждать, или только в лес забежав обратно я их встречу? (проверить не могу, зелья еще не заимел ;) Добавление от 10/03/07, в 03:03:14
да, упустил еще одну деталь. если тот же флаги того же меча записать так: flags = ITEM_SWD | ITEM_MULTI; (то есть не плюсовать флаги) по аналогии с просто "факелом" flags = ITEM_BURN | ITEM_TORCH | ITEM_MULTI; то одетое оружие невозможно продать, пока его не снимешь. то есть как в оригинале, но "одеваются" сразу все 10 мечей ;) видимо, эта особенность и побудила разрабов оружие сделать отдельными клетками. ладно бы оно еще и портилось (ухудшалось), но тут явная недоработка.
|
|
|
03.10.2007, 03:21
|
#1840
|
|
|
|
|
A.G.F.C.
Регистрация: 04.09.2006
Сообщений: 20
|
|
|
|
|
|
Re: М: Скриптинг в Готике
2HikeR: Да, по игре рун очень мало т.к. камушки для них тяжело найти, и смысл их склавывать тоже не велик. ;) Во поводу оружия, что значит плюс??? *:o flags = ITEM_SWD + ITEM_MULTI;Это не верная конструкция, правильно будет так: flags = ITEM_SWD | ITEM_MULTI;Удалять флаги оружия (ITEM_AXE или ITEM_SWD, категорически нельзя!!!). Они отвечают за тип оружия и анимацию используемую Гг в бою.
вставляет когда ГГ все таки подойдет (если подойдет) к конечной точке?
|
Не Гг подойдет, а его восприятие непеся прекратится, после чего, двиг сразу вставит Нпс куда нужно, предварительно удалив из точки на которой непесь стоял. Движок оперирует какой-то константой(ми) которые привязаны к восприятию Гг,
(скорее всего прописано в двиге)
|
и как только Гг теряет ссылку фокуса на определенного Нпс который был до этого активен, и у этого Нпс, имеется распорядок дня, с переходом на другой вейпоинт, с большой дистанцией между старым и новым вейтоинтом. Персонаж появляется обычно стоя, после того как вставится в мир запускается функция распорядка дня, определяющая выполнение распорядка дня для этого вейпоинта. Т.е., все действия в скриптах для Нпс привязываются к распорядку дня Нпс, распорядок привязывается к вейпоинтам, от вейпоинта зависит что конкретно будет делать на нем персонаж/монстр, для этого идут в ход функции ТА. Примерно где-то так. *;) Добавление от 10/03/07, в 03:32:32
да, упустил еще одну деталь. если тот же флаги того же меча записать так: flags = ITEM_SWD | ITEM_MULTI; (то есть не плюсовать флаги) по аналогии с просто "факелом" flags = ITEM_BURN | ITEM_TORCH | ITEM_MULTI; то одетое оружие невозможно продать, пока его не снимешь. то есть как в оригинале, но "одеваются" сразу все 10 мечей видимо, эта особенность и побудила разрабов оружие сделать отдельными клетками. ладно бы оно еще и портилось (ухудшалось), но тут явная недоработка.
|
Хм.. да есть такое... Попробуй использовать проверку активного оружия перед торговлей, если оружие активно, т.е. взято Гг в руки, то снимай его функцией спрятать оружие, запуская одновременно торговлю. ;) Может так сработает ? ::) Добавление от 10/03/07, в 03:35:01
Хм.. кстати по поводу факелов, из всей их кучи используется именно один факел ;) прием он становится сгоревшим и отделяется мож тут еще стоит порыться как оно реализовано? Ведь при использовании факела, 10 факелов не иктивируются сразу, имхо. :)) Добавление от 10/03/07, в 03:41:55
Поправим ошибки...
|
|
|
Здесь присутствуют: 4 (пользователей: 0 , гостей: 4)
|
|
Ваши права в разделе
|
|
|
|
Текущее время: 14:51. Часовой пояс GMT +4.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|