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

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

Исправления скриптов Готики 1

Статус
В этой теме нельзя размещать новые ответы.

Kerrax

Почетный форумчанин
Регистрация
19 Фев 2008
Сообщения
222
Благодарности
682
Баллы
220
Эта тема - для замеченных очевидных недочетов и недоработок в скриптах Готики 1, и предложений по их исправлению. Речь здесь про недочеты только скриптинга, а не сюжета или баланса.
 

Kerrax

Почетный форумчанин
Регистрация
19 Фев 2008
Сообщения
222
Благодарности
682
Баллы
220
В режиме боя магией при беге не слышно шагов героя, потому что анимация "s_MagRunL" (см. файл humans.mds)
не включает звуки шагов (*eventSFXGrnd (12 "Run") и *eventSFXGrnd (21 "Run") ) аналогично анимации "s_RunL".
Надо бы исправить файл humans.mds и перекомпилировать.


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Когда ГГ погибает, он получает опыт за убийство самого себя, что не очень правильно.
Вдобавок получение опыта могло привести к level-up'у, а level-up в свою очередь мог прибавить здоровья ГГ.
Исправить этот глюк, отредактировав файл _work\data\Scripts\content\AI\ZS_Human\ZS_Dead.d
Вроде для этого достаточно поменять там условие на такое:
if !Npc_IsPlayer(self) && (Npc_IsPlayer (other)
|| (C_NpcIsHuman (other) && other.aivar[AIV_PARTYMEMBER])
|| (C_NpcIsMonster(other) && other.aivar[AIV_MM_PARTYMEMBER]))
{
B_DeathXP();
};


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Заклинание "свет" не столько светит, сколько ослепляет.
Исправить это можно, сделав менее заметным источник света, этакое маленькое солнце.
Для этого надо отредактировать файл PFXMagic.d, описание инстанции MFX_LIGHT_ORIGIN.
Можно поиграться с альфа-каналом (параметры visalphastart/visalphaend),
но проще было бы поэкспериментировать с постепенным убываниеи числа частиц,
используемых для изображения источника света, например, так:
ppsvalue = 250;
ppsscalekeys_s = "1 0.2 0.1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0.3 0.2";
ppsfps = 0.2;
ppsIsSmooth = 1;

Каждое число в средней строке умножается на ppsvalue и получается количество частиц в секунду,
при этом 1/ppsfps дает число секунд, в течении которых генерируется это число частиц каждую секунду,
т.е. в течении первых пяти (1/0.2) секунд будет генерироваться 250 * 1 = 250 частиц в секунду,
в течении следующих пяти секунд будет генерироваться 250 * 0.2 = 50 частиц в секунду,
в течении следующих пяти секунд будет генерироваться 250 * 0.1 = 25 частиц в секунду,
потом источник света пропадет (частицы генерироваться перестанут) на (число нулей) * 5 = 54 * 5 = 270 секунд,
потом в конце (последние 15 секунд) появится снова.

Общая длительность заклинания "свет" в секундах определяется как произведение
числа вещественных чисел в строке ppsscalekeys_s на величину (1/ppsfps).


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Попытка взять женщину под контроль (Spell_Control) может привести к вылету игры.
Это происходит из-за того, что Spell_Logic_Control запустит у нее состояние ZS_PsiDefense
(для которого нет соответствующей анимации "S_CON_VICTIM"), которое затем в функции
B_StopPsiDefense запустит у женщины мужское состояние ZS_AssessEnemy, которое при угрозе
вызовет опять же мужское состояние ZS_Flee (а не ZS_Babe_Flee), которое попытается
наложить оверлей HUMANS_FLEE.MDS поверх модели BABE.MDS. Разное число костей
у оверлея и анимации приводит движок к непредвиденному результату, вплоть до вылета.
Решение проблемы - переписать Spell_Logic_Control, включив туда проверку, что Npc - женщина
(чтобы даже не начинать у нее состояние ZS_PsiDefense).


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


При воспроизведении анимации Firespit из концерта In-Extremo (махание двумя факелами и выдыхание огня)
горит факел только в правой руке, факел в левой руке не горит.
Возможно, это происходит из-за того, что анимация "t_FIRESPIT_Stand_2_S0" указывает
*eventTag (1 "DEF_CREATE_ITEM" "ZS_LEFTHAND" "ItLsTorch")
вместо
*eventTag (1 "DEF_CREATE_ITEM" "ZS_LEFTHAND" "ItLsTorchBurning")


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


При проигрывании у NPC анимаций поедания/выпивания часто из рук NPC пропадают предметы,
хотя анимации еды/питья продолжают идти дальше. Происходит такое из-за того, что функция
ZS_StandAround_Loop, которая и включает анимации еды/питья, забывает соответственно
изменить BodyState на BS_ITEMINTERACT. В результате BodyState остается в состоянии BS_RUN,
а функция AI_TurnToVob удаляет все предметы из рук персонажа, если BodyState == BS_RUN или BS_STAND.
(Функцию AI_TurnToVob иногда вызывает сама ZS_StandAround_Loop, когда детектирует кого-то рядом).
Исправить это легко, как кажется - достаточно везде, где запускается анимация еды/питья,
в скриптах AI_PlayAni заменить на AI_PlayAniBS:
AI_PlayAni (self,"T_FOODHUGE_RANDOM_1") -> AI_PlayAni (self,"T_FOODHUGE_RANDOM_1",BS_ITEMINTERACT)
AI_PlayAni (self,"T_POTION_RANDOM_1"); -> AI_PlayAni (self,"T_POTION_RANDOM_1",BS_ITEMINTERACT);
и так далее в файле "B_ZS.d". В Готике 2 так и сделано.


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


В Готике 1 многие металлические по сути топоры имеют тип материала MAT_WOOD. Например, орковские топоры.
Это не очень хорошо, т.е. искры при фехтовании не рисуются.
Тип материала для холодного оружия влияет на звук, с которым оружие сталкивается при блокировании,
на искры при столкновении, а также на звук, с которым оружие падает на пол.
При блокировании мечом топора движок пытается воспроизвести искры CPFX_IAI_WOOD_METAL (деревом ударили по металлу),
но такой инстанции в файле pfx.d нет, и искры не появятся.
Думаю, будет логичнее всему железному оружию поставить тип звукового материала MAT_METAL.
В Готике 2 так и сделано.

Если та часть оружия, которая наносит урон, деревянная и должна быть, то тип материала надо оставить MAT_WOOD.
Например, дубина повреждает именно деревянной частью.
Если дубина блокирует меч, искры не нужны. Но не помешает анимация летящих щепок.
Чтобы ее сделать, достаточно в Sfx.d прописать инстанцию CS_IAI_ME_WO, добавив туда pfxname="CPFX_Wood".

Вообще при столкновении оружий могут воспроизводиться до двух эффектов частиц:
первый: CPFX_IAI_XXXX_XXXX (если определен в pfx.d)
второй, чье имя указано в параметре pfxname инстанции "CS_IAI_XX_XX" звука, проигрываемого при ударе.


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


При ударе мечом об землю воспроизводится неверный звук (Г1).
Происходит это из-за того, что в файле Sfx.d нет соответствующей инстанции "CS_IAO_ME_EA"
(MEtal Attack EArth), и поэтому воспроизводится заменитель "CS_IHL_ME_EA".

Вообще при ударе оружием о меш уровня наш движок пытается воспроизвести звук и эффект частиц вначале
из инстанции "CS_IAL_ME_EA", потом, если инстанция не найдена, из "CS_IAO_ME_EA",
потом, если опять не найдено, из "СS_IHL_ME_EA".

Примечание: движок оригинальной Г2 ведет себя иначе: там сразу воспроизводится "СS_IHL_ME_EA",
без каких-то дополнительных проверок.
Примечание2: движок оригинальной Г1 вообще не воспроизводил каких-либо звуков при ударе о меш уровня,
поэтому там эта проблема была неактуальной.


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Функция ZS_ATTACK() забывает установить aivar[AIV_LASTTARGET] для атакующего,
однако функция ZS_Attack_End считает, что этот aivar установлен.
aivar[AIV_LASTTARGET] устанавливается только в функции ZS_Attack_Loop.
Проблема в том, что число вызовов функции ZS_Attack_Loop может быть любым,
в том числе и нулевым, тогда этот aivar так и не будет установлен до вызова ZS_Attack_End,
в результате чего будет произведена попытка получить указатель на инстанцию непися из нулевого aivar'а,
что приводит к вылету игры.

Возможное решение: исправить ZS_Attack, добавив туда строку
self.aivar[AIV_LASTTARGET] = Hlp_GetInstanceID(other);


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Если будет желание сделать так, чтобы на маленьких картах (Старый лагерь, Новый лагерь, Болотный лагерь)
отображалась стрелочка, указывающая положение героя и куда он смотрит, то для этого достаточно исправить скрипт
MissionItems_1.d, изменив (стиль Г1):
а) в функции UseOCmap "Обзор старого лагеря" строчку Doc_SetLevel("WORLD.ZEN") на:
Doc_MapCoordinates("WORLD.ZEN", -11975, -9675, 0, 0, 11775, 7875, 687, 511);
б) в функцию UseNCmap "Обзор нового лагеря" строчку Doc_SetLevel("WORLD.ZEN") на:
Doc_MapCoordinates("WORLD.ZEN", -64875, -1775, 0, 0, -41125, 15775, 687, 511);
в) в функцию UsePSImap "Обзор болотного лагеря" строчку Doc_SetLevel("WORLD.ZEN") на:
Doc_MapCoordinates("WORLD.ZEN", 33750, -21500, 0, 0, 67050, 2600, 687, 511);
Аналогично с картой храма Спящего.

Функция Doc_MapCoordinates была изменена в gengine, так что теперь она работает и с картами,
созданными с помощью функции Doc_CreateMap.
За выбор того, какую карту отображать по нажатию кнопки M, в движке отвечает функция
PLAYER_HOTKEY_SCREEN_MAP, а если такой функции нет, то используется карта с именем
"ITWR_MAP_" + имя_мира (без расширения .ZEN), а если ее нет в инвентаре (или вообще нет),
то используется карта с именем ITWRWORLDMAP_ORC или ITWRWORLDMAP, какая есть.


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Рисовые поля перед Новым Лагерем имеют тип материала WATER, что несколько неправильно.
Может, оно конечно так и планировалось, только с новой фичей брызг при беге по отмели
слишком уж брызгается, выглядит странно.


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Почему-то мувер EVT_OW_LOCKOUT_TRIGGER (рядом с точкой старта, по пути к заброшенной шахте,
там, где два стражника стоят) не подключен к управляющему колесу. Наверное, просто забыли подключить.


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Замечено, что персонаж, находящийся под заклинанием контроля, может использовать мобы, поворачивать рычаги,
нажимать кнопки и открывать сундуки. Можно это неплохо задействовать, например, в ситуации, когда
ГГ за решеткой, а открывающий решетку рычаг снаружи, - берем непися под контроль, приказываем ему
нажать рычаг, и мы уже на свободе. Или можно взять под контроль непися с ключом от сундука,
чтобы открыть его же сундук.


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


В файле species.d можно подправить значения SURFACE_ALIGN для некоторых гильдий.
Вообще поле SURFACE_ALIGN задает выравнивание модели монстра вдоль поверхности, на которой он стоит.

Расшифровка значений:
0: нет выравнивания - используется для прямоходящих двуногих существ (человек, орк, гоблин, голем, падальщик).

1 или 2: выравнивание оси Z, т.е. персонаж наклоняется вперед/назад вдоль поверхности, - используется для
существ с близким расположением левых и правых ног (волк, мракорис, лошадь).
Если сделать велосипед/мотоцикл (например), то нужно будет также использовать этот тип выравнивания.
Выбор значения 1 или 2 влияет на выбор точки, из которой будут испускаться лучи трассировки для определения,
куда может ступить персонаж. Значение 1 заставляет движок испускать лучи из позиции Bip01,
значение 2 заставит движок испускать лучи из более верхней точки персонажа.
Т.е. если высота ступеньки, на которую с ходу может заскочить персонаж, ниже позиции Bip01,
то надо использовать 1, иначе 2.

3 или 4: выравнивание оси Z и оси X, т.е. персонаж наклоняется вперед/назад и вправо/влево вдоль поверхности,
- используется для существ с широко расставленными ногами (ящерица, люркер, краулер(ползун)).
Использование константы 3 или 4 автоматически отключает auto-rolling (т.е. устанавливает DISABLE_AUTOROLL равным единице).
Различие между константами 3 и 4 такое же, как и между константами 1 и 2.

Для мертвого монстра движок использует SURFACE_ALIGN, равный 3 (в оригинале - 1),
независимо от того, какое значение использовалось, когда монстр был жив.

Оригинальный движок поддерживал только константы 0, 1, 2, константы 3-4 были добавлены только в модифицированный движок.
Соответсвенно, неплохо бы подправить скрипты, заменив для люркера, ящерицы, краулера, 1 на 3, а 2 на 4.


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Обнаружена опечатка в файле PILLAR_7M.MDS (каменный столб, например, в заброшенном монастыре)
- две фигурные скобки вместо одной. Это не мешает движку читать такой MDS-файл, однако
анимации "s_S1" и "t_S1_2_S0" в результате пропадают, о чем пишется warning:
Warn: D: zCModelAni: Could not find nextAni: S_S1, this: T_S0_2_S1
У столба в заброшенном монастыре есть и еще проблемы - не попадает в фокус, падает не в ту сторону.
Хотя там надо разбираться, скорее всего и модель тоже править надо.


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Было бы полезно подправить waynet, устранив проблемы, препятствующие перемещению Npc.
Пояснение: сетку путей (waynet) надо прокладывать так, чтобы Npc мог свободно перемещаться между соседними вейпоинтами.
При этом, чтобы Npc мог воспользоваться лестницей (oCMobLadder), надо, чтобы один вейпоинт был у основания лестницы,
второй - наверху лестницы, причем соединяющая эти два вейпойнта линия обязательно должна пересечь ограничивающий параллелепипед
лестницы. Никаких промежуточных вейпоинтов (в середине подъема) быть не должно.
Если это условие не выполнено, Npc пользоваться лестницей не сможет.

Чтобы Npc мог воспользоваться дверью (oCMobDoor), надо, чтобы один вейпоинт был четко с одной стороны двери,
второй - четко с другой стороны двери. При этом соединяющая эти два вейпойнта линия обязательно
должна пересечь дверь, причем желательно только одну, и желательно в середине двери.
Если надо, чтобы Npc прошел через несколько дверей, то надо просто добавить промежуточные вейпойнты.
В оригинальной Г1 есть проблемы в 3 местах:
путь между вейпоинтами OCC_BARONS_UPSTAIRS_RIGHT_BACK_EXIT и OCC_GREATTOWER_2NDSTORE,
путь между вейпоинтами OCC_STABLE_TO_CORRIDOR и OCC_MERCS_RIGHT_ROOM_FRONT,
путь между вейпоинтами OCC_MERCS_UPPER_LEFT_ROOM_BACK_2 и OCC_LEFT_TOWER_UPPER_ROOM,
- эти три пути содержат по две двери, что, хотя и допускается, может привести к проблемам при поиске пути для NPC.
Правда, в указанных местах NPC ходят мало, так что проблемы здесь особой нет.

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

Функцию B_MoveMob надо заменить на такую:
func void B_MoveMob()
{
PrintDebugNpc(PD_ZS_FRAME,"B_MoveMob");
Npc_ClearAIQueue(self);
AI_StartState(self,ZS_WaitForPassage,0,"");
};

Функции состояния ZS_WaitForPassage надо заменить на такие:
func void ZS_WaitForPassage()
{
PrintDebugNpc(PD_ZS_FRAME,"ZS_WaitForPassage");
C_ZSInit();
Npc_PercEnable(self,PERC_ASSESSDAMAGE,ZS_ReactToDamage);
Npc_PercEnable(self,PERC_ASSESSMAGIC,B_AssessMagic);
Npc_PercEnable(self,PERC_ASSESSWARN,B_AssessWarn);
Npc_PercEnable(self,PERC_ASSESSFIGHTSOUND,B_AssessFightSound);
Npc_PercEnable(self,PERC_CATCHTHIEF,ZS_CatchThief);
Npc_PercEnable(self,PERC_OBSERVEINTRUDER,B_ObserveIntruder);
Npc_PercEnable(self,PERC_ASSESSTALK,B_AssessTalk);
self.aivar[AIV_MOVINGMOB] = 1;
};

func int ZS_WaitForPassage_Loop()
{
PrintDebugNpc(PD_ZS_LOOP,"ZS_WaitForPassage_Loop");
if(!Npc_IsWayBlocked(self))
{
PrintDebugNpc(PD_ZS_Check,"...Path is no longer blocked!");
return LOOP_END;
};
var string door;
door = Npc_GetDetectedMob(self);
PrintDebugNpc(PD_ZS_Check,ConcatStrings("...mob: ",door));
if(Hlp_StrCmp(door,"DOOR"))
{
PrintDebugNpc(PD_ZS_Check,"...mob is a door!);
var int state = Wld_GetMobState(self,"DOOR");
PrintDebugNpc(PD_ZS_Check,ConcatStrings("...door's state: ", IntToString(state));
if(state == 0)
{
PrintDebugNpc(PD_ZS_Check,"...opening the door");
AI_UseMob(self,door,1);
AI_Wait(self,0.5);
}
else if(state == 1)
{
PrintDebugNpc(PD_ZS_Check,"...leaving the door open");
AI_UseMob(self,door,-1);
};
};
return LOOP_CONTINUE;
};

func void ZS_WaitForPassage_End()
{
PrintDebugNpc(PD_ZS_FRAME,"ZS_WaitForPassage_End");
self.aivar[AIV_MOVINGMOB] = 0;
};


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


В функции ZS_SleepBed_Loop надо поменять сравнение
!C_BodyStateContains(self,BS_MOBINTERACT)
на
!C_BodyStateContains(self,BS_MOBINTERACT_INTERRUPT)

Вариант 2. Написать в gengine.ini:
fixMobBodyStates=1 (новый параметр, работает только в gengine)
чтобы задействовать состояния тел из Г2, и тогда уже написать условие как в Г2:
!C_BodyStateContains(self, BS_LIE)

Примечание: состояние тела BS_LIE для лежащего на кровати человека выставляет Готика 2.
Готика 1 ошибочно выставляла состояние тела BS_MOBINTERACT_INTERRUPT, что, впрочем тоже не подходило
под условие в ZS_SleepBed_Loop. В итоге в Готике 1 никто не может долго спать на кровати.


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


В храме Спящего надо проверить триггеры.
Во-первых, для всех TRIGGERFELD'ы, кроме тех, что привязаны к кнопкам на стенах (включаемых выстрелом):
EVT_TPL_08_TRIGGERFELD_01, EVT_TPL_08_TRIGGERFELD_02, EVT_TPL_08_TRIGGERFELD_ABSCHUSS_01 и т.д.
надо установить reactToOnDamage и respondToObject в FALSE, потому что эти триггеры должны срабатывать
только от касания ГГ, а не от пролетающей стрелы (в текущем виде триггеры могут сработать
от пролетевшей стрелы и, например, закрыть решетку (EVT_TPL_08_TRIGGERFELD_02), в итоге игра сразу станет непроходимой!).
Так что для этих триггеров надо оставить установленными в TRUE только reactToOnTouch и respondToPC.

Во-вторых, триггеры, управляющие кнопками на стенах: EVT_TPL_16_BUTTONTRIGGERFELD_01,
EVT_TPL_16_BUTTONTRIGGERFELD_02, EVT_TPL_14_TRIGGERFELD_01.
Включаются эти триггеры выстрелом из лука/арбалета, поэтому для них надо
установить reactToDamage в TRUE, а reactToOnTouch в FALSE (лучше) или наоборот.
Иначе стрела вызовет двойное срабатывание триггера - от урона и от касания, что может привести к глюкам.

Далее, сами кнопки на стенах: EVT_TPL_16_TARGETSTONE_01, EVT_TPL_16_TARGETSTONE_02.
Надо сильно увеличить stayOpenTimeSec (время нахождения кнопки в нажатом состоянии),
скажем, до 100-300 секунд, чтобы каждая кнопка сработывала только один раз,
иначе нет никакого смысла искать обе кнопки, можно выстрелить в одну кнопку, но дважды.
Для кнопки EVT_TPL_14_TRIGGERFELD_01 лучше тоже выставить moverBehavior в 2STATE_OPEN_TIME,
и stayOpenTimeSec поставить не меньше 40-60 секунд.

У мувера EVT_TPL_05_DOOR_01 (дверь на пути к одному из шаманов) лучже сменить
moverBehavior с 2STATE_TOGGLE на 2STATE_TRIGGER_CTRL. Хотя работает и так, просто
кнопку приходится жать дважды. (Кнопка EVT_TPL_05_SWITCH_01, управляющая движением этой двери,
посылает ей по очереди два сообщения: TRIGGER и UNTRIGGER, а мувер с moverBehavior == 2STATE_TOGGLE
реагирует только на TRIGGER.)
Там же рядом есть триггер EVT_TPL_08_TRIGGERFELD_ABSCHUSS_01, который управляет решеткой и шипами.
Этот триггер по идее должен бы еще и кнопки нажимать (там две кнопки рядом на стене), иначе для игрока неочевидно,
как они работают.

Типы объектов EVT_TPL_TRIGGER_SLEEPERHEARTS_01..EVT_TPL_TRIGGER_SLEEPERHEARTS_05 (сердца шаманов около Спящего)
должны быть oCMobItemSlot, а не oCMobInter. Дело в том, что eventTag "DEF_PLACE_ITEM" нормально работает только
с объектами типа oCMobItemSlot, у которых есть слот ZS_SLOT.
Если для сердец шаманов поставить правильный тип (т.е. oCMobItemSlot), то мечи, вставленные в сердца,
остануться торчать в них, а не исчезнут.


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Надо передвинуть некоторые вобы LAVA* типа oCTouchDamage в храме Спящего, которые отвечают за урон при попадании в лаву.
Эти вобы срабатывают от касания, и неверное их размещение приводит к тому, что, с одной стороны,
в некоторых местах можно спокойно гулять по лаве (лава твердая, а не жидкая?!),
а в других местах ГГ погибает, даже не прикоснувшись к лаве.
Например, LAVA_PRIEST_04_02 надо опустить ниже. Иначе можно случайно коснуться этого воба и не попадая в лаву,
а просто подпрыгнув и приземлившись в коридоре рядом с тем местом, где лежит дневник строителя храма Спящего.


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Скрипт последнего мертвого орка-шамана в храме Спящего (ORC_Priest_5) глючит.
Если не подходить к нему слишком близко, и атаковать из лука, то он не будет атаковать в ответ.
Так происходит потому, что для этого шамана установлено npcType = NPCTYPE_FRIEND (друг ГГ),
и поэтому функция ZS_ReactToDamage не вызывает атаки.
Вдобавок, функция ZS_ReactToDamage для "дружественного" шамана вызывает Npc_SetTempAttitude(self,ATT_ANGRY),
что может перебить настройку ATT_HOSTILE, и шаман потом вообще больше ГГ не атакует.
Т.е. основная проблема в параметре npcType = NPCTYPE_FRIEND для этого шамана.
Думаю, "другом" ГГ его сделали для того, чтобы он вначале поговорил с ГГ, а потом уже атаковал.
Лучше бы это переделать: убрать дружбу с ГГ, а взамен переопределить в состоянии ZS_Intercept функцию,
обслуживающую PERC_ASSESSENEMY, чтобы шаман вначале разговаривал с ГГ.


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Скрипт, заставляющий Спящего кидаться огненными шарами (см. функцию ZS_Sleeper_loop),
срабатывает только когда переменная SLF_FIRE == TRUE, а эта переменная устанавливается только после
смерти Кор-Галома (GUR_1212_MadCorKalom), причем смерть эта должна быть на глазах его учеников,
иначе не сработает функция B_OTMeditate_AssessMurder.
Если заманить Кор-Галома подальше и убить, то переменная SPL_FIRE останется равной FALSE.
Если убивать Кор-Галома руной "Волна смерти Уризеля", то Кор-Галом умрет после своих учеников (которые слабее его),
и переменная SPL_FIRE опять же останется равной FALSE. В результате Спящий не будет кидаться огненными шарами,
что сильно упростит его убиение.
Как это исправить: добавить строчку "SPL_FIRE = Npc_IsDead(GUR_1212_MadCorKalom);"
в начало функции ZS_Sleeper_loop, а также добавить в функцию ZS_OTMeditate_Loop активизацию
учеников Кор-Галома в случае его смерти (даже если они ее не видели).


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


В случае необходимости сделать скриншот, в игре есть возможность временно убрать все статусные панели с экрана.
Для этого служит команда консоли "TOGGLE DESKTOP". Предварительно можно еще ввести в ту же консоль команду "ZHIGHQUALITYRENDER",
чтобы улучшить качество картинки (за счет снижения FPS).


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Огненный голем перестает гореть, когда идет (не бежит).
Это происходит потому, что анимация "s_FistWalkL" в файле GOLEM_FIREGOLEM.MDS
не содежит эффектов горения.


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


В русской версии Готики 1 в окне выбора загружаемой игры имя мира отображается в неправильном месте.
Чтобы это исправить, надо в файле "menu_savegame.d" в инстанциях MENUITEM_LOADSAVE_LEVELNAME,
MENUITEM_LOADSAVE_LEVELNAME_VALUE вместо неправильной координаты:
posx = -4000;
записать правильную, как в немецкой версии:
posx = SAVEGAME_X2;


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Для некоторых котлов (CAULDRON_OC.ASC) в Новом Лагере в спейсере не присвоено значение полю useWithItem
(должно быть useWithItem=string:ITMISCOOP), в результате чего ГГ мешает котел без ложки,
т.е. анимация выглядит неправильно.


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


В функции ZS_AssessBody_RecoverWeapon (NPC грабит лежачего) строчка
if((Wld_DetectItem(self,ITEM_KAT_NF) || Wld_DetectItem(self,ITEM_KAT_FF)) && (Npc_GetDistToItem(self,item) < 300))
работает неправильно (и может изредка привести к вылету), т.к., во-первых, игра проверит вторую часть условия (после &&) все равно,
даже если первая часть даст FALSE, а во-вторых, игра вызовет все эти функции в таком порядке:
Npc_GetDistToItem, Wld_DetectItem, Wld_DetectItem (справа налево), т.е. при вызове Npc_GetDistToItem игра еще не будет
знать, расстояние до какого итема измерять.
Исправить этот кусок можно, переписав его как в Г2 (функция ZS_RansackBody_End):
if(Wld_DetectItem(self,ITEM_KAT_NF) || Wld_DetectItem(self,ITEM_KAT_FF))
{
if(Hlp_IsValidItem(item))
{
if(Npc_GetDistToItem(self,item) < 500)
{
т.е. надо четко указывать, в каком порядке что выполнять.


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Мясные жуки неподалеку от второго выхода из Старого Лагеря не ползают по свалке, как должны, а собираются
на тропинке. Это происходит потому, что на свалке мало вобспотов (zCVobSpot) с именами FP_MEATBUG_SPAWN_*,
или они плохо расположены. Надо располагать вобспоты так, чтобы мясной жук (а он маленького роста)
мог видеть с одного вобспота хотя бы один другой вобспот. Если это условие не выполнено,
то функция ZS_MM_Rtn_Wusel_loop направит жуков на ближайший вейпоинт (zCVobWaypoint) - OCR_OUTSIDE_HUT_Z3,
что собственно и наблюдается в игре.


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Функция ZS_MagicFreeze напрасно, как кажется, содержит строку:
Npc_PercEnable(self, PERC_ASSESSMAGIC, ZS_MagicFreeze);
- после этой строки все дальнейшие заклинания (даже не заморозка), будут возобновлять заморозку,
в результате чего заморозка никогда не кончится.


-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 

Robar _III

Забанен
Регистрация
5 Дек 2011
Сообщения
225
Благодарности
7
Баллы
185
А можешь выложить уже готовые файлы в виде патча?
 

Kerrax

Почетный форумчанин
Регистрация
19 Фев 2008
Сообщения
222
Благодарности
682
Баллы
220
А можешь выложить уже готовые файлы в виде патча?
Во-первых, я эти "готовые" файлы просто никогда целиком не делал, написанное выше лишь набор предлагаемых правок. Во-вторых, ряд вещей из написанного еще бы потестить надо. Вдобавок, тема предполагает некоторое обсуждение: если кто-то проверит что-то из написанного здесь и предложит поменять, пишите об этом. Вообще хотелось бы собрать общий список исправлений в скриптах/локациях Г1. Потом этот список можно будет использовать не только для исправления Г1, но и некоторых модов для нее (т.к. моды содержат скрипты тоже).
 

alex_draven


Модостроитель
Регистрация
13 Сен 2007
Сообщения
2.183
Благодарности
2.880
Баллы
420
Почему-то думается, что полезнее была бы скриптовая болванка со всеми исправлениями и добавлением новых функций. Исправление только Готики 1, если хотите. Тратить же силы на мелкие правки каких-то левых модов не лучшее решение.
Лично мне интересны модели, потому готов ковырять в этом напрвлении всё, что угодно. Есть шаблоны мужских, женских, детских моделей, шаблоны боевки. Лишь бы поддержка в движке обеспечивала их работу. А если корни будут уходить в скрипты, без проблем проверю и эту часть. О чем непременно отпишу.
 

Fritz

Участник форума
Регистрация
6 Июн 2007
Сообщения
19
Благодарности
0
Баллы
155
>Почему-то думается, что полезнее была бы скриптовая болванка со всеми исправлениями и добавлением новых функций.
Такую болванку можно сделать на основе исправленных скриптов от hrr.
 

MaGoth

★★★★★★★★★★★
Администратор
Регистрация
7 Янв 2003
Сообщения
19.367
Благодарности
7.815
Баллы
995
alex_draven, Разгребусь немного со своими делами, думаю сварганим такую... Спишемся вообщем. ;)

Fritz,
Такую болванку можно сделать на основе исправленных скриптов от hrr.
Думаю что эти скрипты будут бесполезны, если их и делать, то только на немецком оригинале... *flowers*
 

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.407
Благодарности
3.232
Баллы
525
Типы объектов EVT_TPL_TRIGGER_SLEEPERHEARTS_01..EVT_TPL_TRIGGER_ SLEEPERHEARTS_05 (сердца шаманов около Спящего)
должны быть oCMobItemSlot, а не oCMobInter. Дело в том, что eventTag "DEF_PLACE_ITEM" нормально работает только
с объектами типа oCMobItemSlot, у которых есть слот ZS_SLOT.
Если для сердец шаманов поставить правильный тип (т.е. oCMobItemSlot), то мечи, вставленные в сердца,
остануться торчать в них, а не исчезнут.
Работает! Только нужно ещё допиливать модель шаманского клинка, чтобы он правильно ложился в руки ГГ и не протыкал святилище насквозь. Но это мелочи. Хуже то, что святилища с пронзёнными сердцами после загрузки сохранения возвращаются в исходное состояние, крышка опускается, а клинок торчит сквозь неё.

В GE, кстати, на финальной стадии анимации, видимо, при выполнения тега "DEF_PLACE_ITEM", следует вылет. В оригинале работает правильно.
 

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.407
Благодарности
3.232
Баллы
525
В режиме боя магией при беге не слышно шагов героя, потому что анимация "s_MagRunL" (см. файл humans.mds)
не включает звуки шагов (*eventSFXGrnd (12 "Run") и *eventSFXGrnd (21 "Run") ) аналогично анимации "s_RunL".
При воспроизведении анимации Firespit из концерта In-Extremo (махание двумя факелами и выдыхание огня)
горит факел только в правой руке, факел в левой руке не горит.
Возможно, это происходит из-за того, что анимация "t_FIRESPIT_Stand_2_S0" указывает
*eventTag (1 "DEF_CREATE_ITEM" "ZS_LEFTHAND" "ItLsTorch")
вместо
*eventTag (1 "DEF_CREATE_ITEM" "ZS_LEFTHAND" "ItLsTorchBurning")
Огненный голем перестает гореть, когда идет (не бежит).
Это происходит потому, что анимация "s_FistWalkL" в файле GOLEM_FIREGOLEM.MDS
не содежит эффектов горения.
Попробовал исправить. Работает. В спойлере вносимые исправления. Возможно, будет полезно тем, кто, также как и я, не особенно разбирается в сценариях анимаций.

Файл HUMANS.MDS

Звук шагов при беге и ходьбе в режиме боя магией.
ani ("s_MagRunL" 1 "s_MagRunL" 0.0 0.0 M. "Hum_MagRun_A01.asc" F 12 31)
{
*eventSFXGrnd (12 "Run")
*eventSFXGrnd (21 "Run")
}


ani ("s_MagWalkL" 1 "s_MagWalkL" 0.0 0.0 M. "Hum_MagWalkLoop_A01.asc" F 10 33)
{
*eventSFXGrnd (10 "Run")
*eventSFXGrnd (22 "Run")
}


Второй горящий факел.
ani ("t_FIRESPIT_Stand_2_S0" 1 "s_FIRESPIT_S0" 0.2 0.0 M. "Hum_FireSpit_M01.asc" F 0 69 FPS:10)
{
*eventTag (1 "DEF_INSERT_ITEM" "ZS_RIGHTHAND")
*eventTag (1 "DEF_CREATE_ITEM" "ZS_LEFTHAND" "ItLsTorch")
*eventTag (1 "DEF_CREATE_ITEM" "ZS_LEFTHAND" "ItLsTorchFirespit")
}

Файл GOLEM_FIREGOLEM.MDS

Эффекты горения при беге и ходьбе.
ani ("s_FistRunL" 1 "s_FistRunL" 0.0 0.0 M. "Golem_Run_M01.asc" F 12 31)
{
*eventSFX (12 "GOL_StepBoom" )
*eventPFX (12 1 "GolemDust" "BIP01 L Foot" ATTACH )
*eventPFX (12 "Firegolem_Fire" "BIP01 L Foot" ATTACH )
*eventCamTremor (12 1000 700 2 8 )

*eventPFX (15 "Firegolem_Fire" "BIP01 Head" ATTACH )

*eventSFX (22 "GOL_StepBoom" )
*eventPFX (22 2 "GolemDust" "BIP01 R Foot" ATTACH )
*eventPFX (22 "Firegolem_Fire" "BIP01 R Foot" ATTACH )
*eventCamTremor (22 1000 700 2 5 )

*eventPFX (25 "Firegolem_Fire" "BIP01 L UpperArm" ATTACH )
*eventPFX (27 "Firegolem_Fire" "BIP01 R UpperArm" ATTACH )
}

ani ("s_FistWalkL" 1 "s_FistWalkL" 0.0 0.0 M. "golem_walk_03d.asc" F 10 49)
{
*eventSFX (22 "GOL_StepBoom" )
*eventPFX (22 1 "GolemDust" "BIP01 R Foot" ATTACH )

*eventPFX (22 "Firegolem_Fire" "BIP01 R Foot" ATTACH )
*eventPFX (26 "Firegolem_Fire" "BIP01 Head" ATTACH )

*eventSFX (42 "GOL_StepBoom" )
*eventPFX (42 2 "GolemDust" "Bip01 L Foot" ATTACH )

*eventPFX (42 "Firegolem_Fire" "BIP01 L Foot" ATTACH )
*eventPFX (46 "Firegolem_Fire" "BIP01 L UpperArm" ATTACH )
*eventPFX (48 "Firegolem_Fire" "BIP01 R UpperArm" ATTACH )
}

Перекомпилировать анимации не нужно. Достаточно внести правки в указанные файлы.

При проигрывании у NPC анимаций поедания/выпивания часто из рук NPC пропадают предметы,
хотя анимации еды/питья продолжают идти дальше. Происходит такое из-за того, что функция
ZS_StandAround_Loop, которая и включает анимации еды/питья, забывает соответственно
изменить BodyState на BS_ITEMINTERACT. В результате BodyState остается в состоянии BS_RUN,
а функция AI_TurnToVob удаляет все предметы из рук персонажа, если BodyState == BS_RUN или BS_STAND.
(Функцию AI_TurnToVob иногда вызывает сама ZS_StandAround_Loop, когда детектирует кого-то рядом).
Исправить это легко, как кажется - достаточно везде, где запускается анимация еды/питья,
в скриптах AI_PlayAni заменить на AI_PlayAniBS:
AI_PlayAni (self,"T_FOODHUGE_RANDOM_1") -> AI_PlayAni (self,"T_FOODHUGE_RANDOM_1",BS_ITEMINTERACT)
AI_PlayAni (self,"T_POTION_RANDOM_1"); -> AI_PlayAni (self,"T_POTION_RANDOM_1",BS_ITEMINTERACT);
и так далее в файле "B_ZS.d".
Работает. Стало гораздо лучше, но есть одно НО. Кое-что всё-таки исчезает. Исчезают Рис (ItFoRice) и Рисовый шнапс (ItFoBooze). При выполнении распорядка StandAround эти предметы исчезают перед сменой предмета, то есть во время выполнения последней анимации с данным предметом. При выполнении функции самолечения после боя эти предметы исчезают во время их использования. Кроме того, похоже, исчезновение данных предметов происходит только у представителей гильдии воров. Пробовал давать их рудокопам в СЛ, использование происходит правильно, без исчезновения.

Методом тыка выяснил, что проблема связана с инстанциями предметов. Создал копии инстанций с изменёнными названиями (ItFoRice_01 и ItFoBooze_01), прописал их в функциях поедания/выпивания, исчезновения прекратились. *???*
 

Xentar

Участник форума
Регистрация
26 Май 2007
Сообщения
40
Благодарности
3
Баллы
155
Попытка взять женщину под контроль (Spell_Control) может привести к вылету игры. Это происходит из-за того, что Spell_Logic_Control запустит у нее состояние ZS_PsiDefense (для которого нет соответствующей анимации "S_CON_VICTIM"), которое затем в функции B_StopPsiDefense запустит у женщины мужское состояние ZS_AssessEnemy, которое при угрозе вызовет опять же мужское состояние ZS_Flee (а не ZS_Babe_Flee), которое попытается наложить оверлей HUMANS_FLEE.MDS поверх модели BABE.MDS. Разное число костей у оверлея и анимации приводит движок к непредвиденному результату, вплоть до вылета. Решение проблемы - переписать Spell_Logic_Control, включив туда проверку, что Npc - женщина (чтобы даже не начинать у нее состояние ZS_PsiDefense).
Можно перебрасывать ее из этого состояния в состояние сна (магического?) типа упала в обморок при попытке контроля )))
 

annakor

Участник форума
Регистрация
6 Янв 2020
Сообщения
8
Благодарности
0
Баллы
95
А можно поинтересоваться: где взять исправленные скрипты 1 готики? У меня лично есть набор, на который не ругается GothicSourser 3.14, но дело было в далёком прошлом и там есть недочёты
 

Волк

Участник форума
Регистрация
21 Дек 2010
Сообщения
63
Благодарности
0
Баллы
170
Заметил что в игре присутствуют 2 спутника первый это Мад и второй который сидит на болоте в хижине но вот незадача что реакции на угрозу у них прописаны к как то странно они сразу убегают должно ли так быть или же это недоделки игры?
Причем второй говорит что не против по бродить с ГГ кого нибудь ограбить а при виде падальщика сразу же убегает обратно в сою хижину.
 

IdeaGen

Участник форума
Регистрация
28 Апр 2017
Сообщения
2.206
Благодарности
580
Баллы
295
Волк, я думаю, это лорные, так сказать, персонажи, задача которых демонстрировать, как жители воспринимают окружающий их мир и уживаются в нем на частных примерах, чтобы иметь понимание, почему тут некоторые хозяева жизни, а другие - выше рудокопов не прыгнут.
 
Статус
В этой теме нельзя размещать новые ответы.
Сверху Снизу