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

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

Не стесняюсь спросить....

Lorddemonik

★★★★★
Редактор раздела
Регистрация
17 Дек 2011
Сообщения
1.113
Благодарности
581
Баллы
350
Этот вопрос, кстати, вроде как уже поднимался. Связан был с тем, что kill через скрипты не давал трупам "уйти". Может стоит через kill + remove убирать нпс из игры?
 

N1kX


Модостроитель
Регистрация
13 Ноя 2009
Сообщения
6.124
Благодарности
5.622
Баллы
910
Гм, я думал, что это особенность движка Г2. Движок не удаляет трупы неписей, у которых есть собственное расписание, привязанное к вейпоинту/вейпоинтам.

Но из твоего описания следует, что если очистить инвентарь, движок непися удалит. Я правильно понимаю?
Так и есть. Очистил инвентарь одного НПС, сделал переход из локации в локацию, труп удалился.

Этот вопрос, кстати, вроде как уже поднимался. Связан был с тем, что kill через скрипты не давал трупам "уйти". Может стоит через kill + remove убирать нпс из игры?
B_KillNpc не используется, мое понимание использовании функции - лишь для того, чтобы Игрок мог увидеть по сюжету смерть какого-то НПС, посмотреть его инвентарь и прочее, для убирания НПС используется функция B_RemoveNpc, она же меняем им расписание на TOT (главное не забыть его сделать).

Решение, как мне кажется не слишком красивое.
Daedalus:
func void B_RemoveNpc(var int npcInstance)
{
    var C_Npc npc;
    npc = Hlp_GetNpc(npcInstance);
    if(Hlp_IsValidNpc(npc) && !Npc_IsDead(npc))
    {
        npc.flags = 0;
        npc.aivar[AIV_DeathInvGiven] = TRUE; //установить факт, что труп был обыскан
        AI_Teleport(npc,"TOT");
        B_StartOtherRoutine(npc,"TOT");
        Npc_ChangeAttribute(npc,ATR_HITPOINTS,-npc.attribute[ATR_HITPOINTS_MAX]);
        AI_Teleport(npc,"TOT");
    };
};
 
Последнее редактирование:

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.407
Благодарности
3.232
Баллы
525
Очистил инвентарь одного НПС, сделал переход из локации в локацию, труп удалился.
А если просто отойти от трупа на 50+ метров и вернуться к месту его расположения?

А вообще, в движке есть функция удаления непися из мира Wld_RemoveNpc. Она, почему-то, не используется скриптерами Пираний ни в Г1, ни в Г2. В Г1 функция работает. Каких-либо проблем при её использовании пока не обнаружено. Пример использования:
Daedalus:
Wld_RemoveNpc(Hlp_GetInstanceID(SFB_1031_Schuerfer));
Нельзя использовать, когда идентификатор self указывает на удаляемого непися. В этом случае происходит вылет. Можно использовать, когда непись находится в зоне действия ИИ и за её пределами. В большинстве случаев, думаю, является разумной альтернативой отправке непися в "морг".
 

N1kX


Модостроитель
Регистрация
13 Ноя 2009
Сообщения
6.124
Благодарности
5.622
Баллы
910
Знаю, использовал, я писал просто инстанцию, тоже проблем нет.
Это в принципе не так важно, морг огромный по размерам, просто удивил факт, что вроде и стоят настройки по удалению трупа, даже с предметами, а он остается.
Выходит движок ориентируется на айвар обчищен труп или нет, тут уж пусть поопытнее скажут, на что ориентируется движок.
 

Scarecrow

Участник форума
Регистрация
11 Авг 2014
Сообщения
162
Благодарности
85
Баллы
220
Объясните пожалуйста такую вещь - когда ГГ вступает в какую-нибудь гильдию, ему предоставляется выбор (Я готов присоединиться/Пока не готов). Если сказать, что не готов, реплика остается, и можно вступить когда угодно, а если вступить сразу, то реплика исчезнет (по крайней мере в г2). Можно ли такое сделать в г1? Такого выбора, по сути, в г1 нет. Пока не получишь одобрения от идолов, можно будет говорить с Кор галомом бесконечно, но как только получил согласие гг вступает в лагерь и реплика исчезает (хотя в скрипте написано permanent = 1). Почему она исчезает и как это сделать?

Попробовал как в г2 написать через var int в story globals. После такого реплика все равно остается и гг говорит свою фразу, но нпс ему ничего не отвечает.
 

Lorddemonik

★★★★★
Редактор раздела
Регистрация
17 Дек 2011
Сообщения
1.113
Благодарности
581
Баллы
350
Объясните пожалуйста такую вещь - когда ГГ вступает в какую-нибудь гильдию, ему предоставляется выбор (Я готов присоединиться/Пока не готов). Если сказать, что не готов, реплика остается, и можно вступить когда угодно, а если вступить сразу, то реплика исчезнет (по крайней мере в г2). Можно ли такое сделать в г1? Такого выбора, по сути, в г1 нет. Пока не получишь одобрения от идолов, можно будет говорить с Кор галомом бесконечно, но как только получил согласие гг вступает в лагерь и реплика исчезает (хотя в скрипте написано permanent = 1). Почему она исчезает и как это сделать?

Попробовал как в г2 написать через var int в story globals. После такого реплика все равно остается и гг говорит свою фразу, но нпс ему ничего не отвечает.
Реплика исчезает, если условия не выполнены. Например игра проверяет, что диалога не будет, если игрок в гильдии. В данном случае условие для диалога то, что игрок НЕ состоит в гильдии
 

Scarecrow

Участник форума
Регистрация
11 Авг 2014
Сообщения
162
Благодарности
85
Баллы
220
Реплика исчезает, если условия не выполнены. Например игра проверяет, что диалога не будет, если игрок в гильдии. В данном случае условие для диалога то, что игрок НЕ состоит в гильдии

В том то и проблема, что даже после вступления в гильдию и изменение гильдии гг, реплика остается.
 

N1kX


Модостроитель
Регистрация
13 Ноя 2009
Сообщения
6.124
Благодарности
5.622
Баллы
910
Посмотри примеры, например у Андрэ.
Daedalus:
instance DIA_Andre_JOIN(C_Info)
{
    npc = MIL_311_Andre;
    nr = 100;
    condition = DIA_Andre_JOIN_Condition;
    information = DIA_Andre_JOIN_Info;
    permanent = TRUE;
    description = "Я готов вступить в ополчение!";
};

func int DIA_Andre_JOIN_Condition()
{
    if((hero.guild == GIL_NONE) && Npc_KnowsInfo(other,DIA_Andre_AskToJoin))
    {
        return TRUE;
    };
};

func void DIA_Andre_JOIN_Info()
{
    AI_Output(other,self,"DIA_Andre_JOIN_15_00");    //Я готов вступить в ополчение!
    if(Andre_Knows_MartinEmpfehlung == TRUE)
    {
        AI_Output(self,other,"DIA_Addon_Andre_JOIN_08_00");    //Интендант Мартин ручается за тебя и даже рекомендует тебя мне. Этого мне достаточно.
        //Log_SetTopicStatus(TOPIC_Addon_RangerHelpMIL,LOG_SUCCESS);
        //new
        b_logstatus(TOPIC_Addon_RangerHelpMIL, LOG_SUCCESS);
        //end
        B_LogEntry(TOPIC_Addon_RangerHelpMIL,"Лорд Андрэ по рекомендации Мартина согласился принять меня в ополчение.");
    }
    else if(Player_IsApprentice > APP_NONE)
    {
        AI_Output(self,other,"DIA_Andre_JOIN_08_03");    //А ты являешься гражданином Хориниса?
        if(Player_IsApprentice == APP_Harad)
        {
            AI_Output(other,self,"DIA_Andre_JOIN_15_04");    //Кузнец взял меня в ученики.
            AI_Output(self,other,"DIA_Andre_JOIN_08_05");    //Гарад? Я знаю его. Он работает на нас. Он достойный человек.
        };
        if(Player_IsApprentice == APP_Constantino)
        {
            AI_Output(other,self,"DIA_Andre_JOIN_15_06");    //Я ученик алхимика!
            AI_Output(self,other,"DIA_Andre_JOIN_08_07");    //У нас, в ополчении, не так уж много ученых мужей. Возможно, твои навыки весьма пригодятся нам.
            AI_Output(self,other,"DIA_Andre_JOIN_08_08");    //Я мало что знаю об алхимии. Но люди говорят, что он уважаемый человек.
        };
        if(Player_IsApprentice == APP_Bosper)
        {
            AI_Output(other,self,"DIA_Andre_JOIN_15_09");    //Боспер, мастер-лучник, взял меня в ученики.
            AI_Output(self,other,"DIA_Andre_JOIN_08_10");    //Тогда ты наверняка знаешь кое-что о том, как выжить в лесу? Это хорошо, потому что ополчению приходится выполнять задачи не только в городе.
            AI_Output(self,other,"DIA_Andre_JOIN_08_11");    //Нам, определенно, нужны люди, умеющие ориентироваться в дикой местности.
            AI_Output(self,other,"DIA_Andre_JOIN_08_12");    //И Боспер уважаемый человек в этом городе.
        };
        AI_Output(self,other,"DIA_Andre_JOIN_08_13");    //Если он поручился за тебя, ничто не мешает твоему вступлению в ряды ополчения.
    }
    else
    {
        AI_Output(self,other,"DIA_Andre_JOIN_08_15");    //Может быть - но ты все еще не гражданин этого города, а у меня есть приказ.
        return;
    };
    AI_Output(self,other,"DIA_Andre_JOIN_08_16");    //Ты можешь вступить в наши ряды, если хочешь. Но твое решение должно быть окончательным.
    AI_Output(self,other,"DIA_Andre_JOIN_08_17");    //После того, как ты наденешь доспехи ополчения, ты уже не сможешь просто так снять его и выйти из наших рядов.
    AI_Output(self,other,"DIA_Andre_JOIN_08_18");    //Ты готов сражаться вместе с нами за Инноса и короля?
    Info_ClearChoices(DIA_Andre_JOIN);
    Info_AddChoice(DIA_Andre_JOIN,"Я пока не уверен...",DIA_Andre_JOIN_No);
    Info_AddChoice(DIA_Andre_JOIN,"Я готов!",DIA_Andre_JOIN_Yes);
};

func void DIA_Andre_JOIN_Yes()
{
    AI_Output(other,self,"DIA_Andre_JOIN_Yes_15_00");    //Я готов!
    AI_Output(self,other,"DIA_Andre_JOIN_Yes_08_01");    //Тогда так тому и быть. Добро пожаловать в ряды ополчения.
    other.guild = GIL_MIL;
    Npc_SetTrueGuild(other,GIL_MIL);
    //Npc_ExchangeRoutine(Lothar,"START");
    B_StartOtherRoutine(Lothar,"START");
    AI_Output(self,other,"DIA_Andre_JOIN_Yes_08_02");    //Вот твои доспехи.
    B_GiveInvItems(self,other,ITAR_Mil_L,1);
    AI_Output(self,other,"DIA_Andre_JOIN_Yes_08_03");    //Носи их с гордостью и достоинством.
    if(MIS_BecomeSLD == Log_Running)
    {
        MIS_BecomeSLD = LOG_FAILED;
        SLD_Aufnahme = LOG_FAILED;
        Log_SetTopicStatus(TOPIC_BecomeSLD,LOG_FAILED);
        Log_AddEntry(TOPIC_BecomeSLD,"Теперь я ополченец, путь в наемники для меня закрыт.");
    };
    if(MIS_Kloster == Log_Running)
    {
        KDF_Aufnahme = LOG_FAILED;
        Log_SetTopicStatus (Topic_Kloster, LOG_FAILED);
        Log_AddEntry(Topic_Kloster,"Теперь я ополченец, путь в маги Огня для меня закрыт.");
        MIS_Kloster = LOG_FAILED;
    };
    if(MIS_GUILDHUN == Log_Running)
    {
        Log_SetTopicStatus(TOPIC_GUILD,LOG_FAILED);
        Log_AddEntry(TOPIC_GUILD,"Теперь я ополченец, путь в охотники для меня закрыт.");
        MIS_GUILDHUN = LOG_FAILED;
    };
    if(MIS_Mroczny_zakon == LOG_Running)
    {
        Log_SetTopicStatus(TOPIC_Mroczny_zakon,LOG_FAILED);
        Log_AddEntry(TOPIC_Mroczny_zakon,"Теперь я ополченец, путь в Темный орден для меня закрыт.");  
        MIS_Mroczny_zakon = LOG_FAILED;
    };
    if(MIS_BECOMEKDW == LOG_Running)
    {
        Log_SetTopicStatus(TOPIC_BECOMEKDW,LOG_FAILED);
        Log_AddEntry(TOPIC_BECOMEKDW,"Теперь я ополченец, путь в маги Воды для меня закрыт.");
        MIS_BECOMEKDW = LOG_FAILED;
    };
    if(RangerHelp_gildeSLD == LOG_Running)
    {
        RangerHelp_gildeSLD = LOG_FAILED;  
        Log_SetTopicStatus(TOPIC_Addon_RangerHelpSLD,LOG_FAILED);
        Log_AddEntry(TOPIC_Addon_RangerHelpSLD,"Теперь я ополченец, поэтому путь в наемники для меня закрыт.");
    };
    if(RangerHelp_gildeKDF == LOG_Running)
    {
        RangerHelp_gildeKDF = LOG_FAILED;
        Log_SetTopicStatus(TOPIC_Addon_RangerHelpKDF,LOG_FAILED);
        Log_AddEntry(TOPIC_Addon_RangerHelpKDF,"Теперь я ополченец, поэтому путь в маги Огня для меня закрыт.");
    };
    MIL_Aufnahme = LOG_SUCCESS;
    MIS_BecomeMIL = LOG_SUCCESS;
    //Log_SetTopicStatus(TOPIC_BecomeMIL,LOG_SUCCESS);
    //new
    b_logstatus(TOPIC_BecomeMIL, LOG_SUCCESS);
    //end
    B_LogEntry(TOPIC_BecomeMIL,"Я теперь принадлежу к ополчению.");  
    B_GivePlayerXP(500);
    Wld_InsertNpc(trollatgolemplace,"FP_MAGICGOLEM");
    Info_ClearChoices(DIA_Andre_JOIN);
};

func void DIA_Andre_JOIN_No()
{
    AI_Output(other,self,"DIA_Andre_JOIN_No_15_00");    //Я пока не уверен...
    AI_Output(self,other,"DIA_Andre_JOIN_No_08_01");    //Если ты еще сомневаешься в своем решении, я не могу принять тебя в ополчение.
    Info_ClearChoices(DIA_Andre_JOIN);
};
В
Daedalus:
func int DIA_Andre_JOIN_Condition()
{
    if((hero.guild == GIL_NONE) && Npc_KnowsInfo(other,DIA_Andre_AskToJoin))
    {
        return TRUE;
    };
};
Идут две проверки:
Есть ли у Безымянного гильдия (в данном случае её нет) и был ли диалог DIA_Andre_AskToJoin (description = "Я хочу поступить на службу к паладинам!" )
Дальше, когда ты соглашаешься вступить в гильдию у тебя идет присвоение новой гильдии
Daedalus:
other.guild = GIL_MIL;
Npc_SetTrueGuild(other,GIL_MIL);
Теперь с новой информацией условие, что выше, просто не выполняется, поэтому диалога нет
Если расписать числами
До вступления
1 && 1 = 1
После вступления
0 && 1 = 0
 
Последнее редактирование:

Scarecrow

Участник форума
Регистрация
11 Авг 2014
Сообщения
162
Благодарности
85
Баллы
220
N1kX, Lorddemonik, А, все, допер таки наконец. Не там условие писал оказывается. Огромное спасибо!
 

Хазариэл

Участник форума
Регистрация
13 Май 2018
Сообщения
53
Благодарности
51
Баллы
170
Вопрос по текстурам) Как убрать этот "блеск" или сияние с доспехов рыцаря? Шлем я скрыл, но из-за этих отблесков видно прорисовку его. Может есть текстура которая отвечает за этот блеск? Я бы ее в альфа-канале скрыл
 

Вложения

  • 2020-06-25_20-00-36.jpg
    2020-06-25_20-00-36.jpg
    250,6 KB · Просмотры: 27

N1kX


Модостроитель
Регистрация
13 Ноя 2009
Сообщения
6.124
Благодарности
5.622
Баллы
910
Если без переделки модели доспеха Armor_pal_m, попробуй тестуру PAL-KetHelm сделать полностью с альфа-каналом, черный фон, и весь закрасить альфа-каналом
 

Хазариэл

Участник форума
Регистрация
13 Май 2018
Сообщения
53
Благодарности
51
Баллы
170
Если без переделки модели доспеха Armor_pal_m, попробуй тестуру PAL-KetHelm сделать полностью с альфа-каналом, черный фон, и весь закрасить альфа-каналом
альфа-канал у меня был на шлеме, но я еще раз попробовал и ничего, попробовал поменять модели с паладином, там тоже сверкает и блестит все.
Посмотрел MDM файл брони, там по тегу TGA только шлем и сама текстура брони и все.
 

N1kX


Модостроитель
Регистрация
13 Ноя 2009
Сообщения
6.124
Благодарности
5.622
Баллы
910
Ну так, шлем убирать надо через 3d редактор (blender/3dmax) и компилировать по новому модель доспеха.
 

ElderGamer


Модостроитель
Регистрация
16 Апр 2008
Сообщения
4.407
Благодарности
3.232
Баллы
525
Может есть текстура которая отвечает за этот блеск?
Это не текстура "сияет". На модель доспеха натянута не текстура, а материал. Материал - это не только текстура, но и набор свойств. Например, такое вот сияние. Ты, как я понимаю, добавил альфу текстуре, используемой в модели доспеха. Да, полигоны шлема стали прозрачными, но эффект, привязанный к материалу, никуда не делся.

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

Ну так, шлем убирать надо через 3d редактор (blender/3dmax)
При этом может слететь привязка вершин модели к костям скелета. Может, и не слетит. Но опасность этого существует.
 

Scarecrow

Участник форума
Регистрация
11 Авг 2014
Сообщения
162
Благодарности
85
Баллы
220
Такой вопрос - а кто нибудь может знает как в мрачных тайнах авторы сделали итемы (загадочная статуэтка и костяшка перемены), которые при начале новой игры раскидываются по случайным местам?
 

N1kX


Модостроитель
Регистрация
13 Ноя 2009
Сообщения
6.124
Благодарности
5.622
Баллы
910
Созданы Freepoint для вставки предмета в zen файле
Потом используется следующий код:
Daedalus:
var int CubePuted;
var int StatuePuted;
func void PutCube ()
{
    //запихиваем в переменную рандомное число
    CubePuted = hlp_random (9)+1;
    
    //здесь мы присаиваем в названию FP рандомное число
    var string CubePlace;
    CubePlace    =    "CUBE_";
    CubePlace    =    ConcatStrings(CubePlace,inttostring(CubePuted));
    
    //делаем вставку на рандомный FP
    Wld_InsertItem (Cube, CubePlace);
    
    //здесь мы присаиваем в названию FP рандомное число
    StatuePuted = hlp_random (9)+1;
    var string StatuePlace;
    StatuePlace    =    "CUBE_";
    StatuePlace    =    ConcatStrings(StatuePlace,inttostring(StatuePuted));
    
    //делаем вставку на рандомный FP
    Wld_InsertItem (RandomStatue, StatuePlace);
    
    /*
    if (CubePuted == 0)    {        Wld_InsertItem (Cube, "NC_PATH50");    }else
    if (CubePuted == 1)    {        Wld_InsertItem (Cube, "OC1");    }else
    if (CubePuted == 2)    {        Wld_InsertItem (Cube, "PSI_START");    }else
    if (CubePuted == 3)    {        Wld_InsertItem (Cube, "FOGTOWER_OUT");    }else
    if (CubePuted == 4)    {        Wld_InsertItem (Cube, "LOCATION_19_03");    }else
    if (CubePuted == 5)    {        Wld_InsertItem (Cube, "OW_ORCBRIDGE");    }else
    if (CubePuted == 6)    {        Wld_InsertItem (Cube, "DT_MAINGATE");    }else
    if (CubePuted == 7)    {        Wld_InsertItem (Cube, "LOCATION_12_01");    };
    */
        CubePuted = 999;
};
 

Scarecrow

Участник форума
Регистрация
11 Авг 2014
Сообщения
162
Благодарности
85
Баллы
220
N1kX, спасибо огромное! я открывал зен файл мрачных тайн, но на тех местах, где появляется куб и статуэтка - вайпоинты, не фрипоинты, но попробую по-разному, спасибо)
а в какой подпапке создавать этот скрипт? прямо в items/misc или где?
 

N1kX


Модостроитель
Регистрация
13 Ноя 2009
Сообщения
6.124
Благодарности
5.622
Баллы
910
Предметы лучше вставлять на Freepoint. На Waypoint предметы висят в воздухе.
Правильнее всего в B_Content/B_Story Gothic 2
В B/Event gothic 1
Ну это мне так кажется, каждый человек пихает скрипты, где ему удобно.
Ну и делаешь потом вызов где нужно.
 

Scarecrow

Участник форума
Регистрация
11 Авг 2014
Сообщения
162
Благодарности
85
Баллы
220
N1kX, блин, все равно не выходит. Как понимаю, что бы это сработало, нужно прописать какое-нибудь условие - попробовал так, что бы заработало после разговора с диего, но все равно не получается. что я делаю не так? может, упустил чего?

var int CubePuted;
var int StatuePuted;
func void PutCube ()
{

if(Npc_KnowsInfo(hero,INFO_DIEGO_GAMESTART))
{

CubePuted = hlp_random (9)+1;
var string CubePlace;
CubePlace = "CUBE_";
CubePlace = ConcatStrings(CubePlace,inttostring(CubePuted));
Wld_InsertItem (crw_armor, CubePlace);

StatuePuted = hlp_random (9)+1;
var string StatuePlace;
StatuePlace = "CUBE_";
StatuePlace = ConcatStrings(StatuePlace,inttostring(StatuePuted));
Wld_InsertItem (crw_armor, StatuePlace);

if (CubePuted == 0) { Wld_InsertItem (crw_armor, "blade"); }else
if (CubePuted == 1) { Wld_InsertItem (crw_armor, "cord"); }else
if (CubePuted == 2) { Wld_InsertItem (crw_armor, "lee"); }else
if (CubePuted == 3) { Wld_InsertItem (crw_armor, "cavalorn"); }else
if (CubePuted == 4) { Wld_InsertItem (crw_armor, "fisk"); }else
if (CubePuted == 5) { Wld_InsertItem (crw_armor, "drax"); }else
if (CubePuted == 6) { Wld_InsertItem (crw_armor, "drak"); }else
if (CubePuted == 7) { Wld_InsertItem (crw_armor, "sly"); };

CubePuted = 999;
};
};
 
Сверху Снизу