dosinabox / g2nr_unofficial_update

Исходники скриптов, релизы, хотфиксы и тестовые версии неофициального обновления для игры "Готика 2: Ночь Ворона".
https://worldofplayers.ru/threads/36817
The Unlicense
13 stars 1 forks source link

prototype Npc_разные #264

Closed Kor-Angar closed 3 years ago

Kor-Angar commented 4 years ago

Хочу проработать прототипы НПС для фракций Менты / Наёмы / Палы и т.д. Пришлось сделать таблицы что бы соблюсти баланс

https://docs.google.com/spreadsheets/d/1tspBhvi9wPY2TOAkHUQTQgijPHVgt1KjjaMSHiy5WDw

Сами прототипы пока добавил в один файл https://github.com/Kor-Angar/G2_NotR_Kor_Angar/blob/master/PrjGOTHIC/Story/NPC_Scripts/Npc_Default.d

Kor-Angar commented 3 years ago

А я всё с тем же вопросом :-) может есть какие то замечания? :-)

prototype NPC_SLD_lvl_40_2h(C_Npc)
{   
    //-------- primary data --------
    name[0] =                       NAME_Soeldner;
    npctype =                       NPCTYPE_AMBIENT;
    guild =                         GIL_SLD;
    level =                         40;
    flags =                         0;          
    //-------- abilities --------
    /*
    //  взято из B_SetAttributesToChapter(4)
        slf.level = 40;
        slf.attribute[ATR_STRENGTH] = 150;
        slf.aivar[REAL_STRENGTH] = 150;
        slf.attribute[ATR_DEXTERITY] = 150;
        slf.aivar[REAL_DEXTERITY] = 150;
        slf.attribute[ATR_MANA_MAX] = 1000;
        slf.attribute[ATR_MANA] = 1000;
        slf.aivar[REAL_MANA_MAX] = 1000;
        slf.attribute[ATR_HITPOINTS_MAX] = 520;
        slf.attribute[ATR_HITPOINTS] = 520;
    */
    attribute[ATR_STRENGTH]  =      150;
    aivar[REAL_STRENGTH]     =      150;
    attribute[ATR_DEXTERITY] =      150; // а надо ли столько?
    aivar[REAL_DEXTERITY]    =      150;
    attribute[ATR_MANA_MAX] =       10;  // срезал до 10
    attribute[ATR_MANA] =           10;  // срезал до 10
    attribute[ATR_HITPOINTS_MAX] =  520;
    attribute[ATR_HITPOINTS] =      520;
    // ------ Grund-Schadensresistenzen: Keine ------
    protection  [PROT_EDGE]             = 0;
    protection  [PROT_BLUNT]            = 0;
    protection  [PROT_POINT]            = 0;
    protection  [PROT_FIRE]             = 0;
    protection  [PROT_MAGIC]            = 0;
    //-------- visuals --------
    // прототипу делать вредно и опасно!!!
    //---------------------------   
    fight_tactic    =   FAI_HUMAN_STRONG;   // MASTER / STRONG / COWARD

    //-------- Talente -------- 
    // в оригинале было     B_SetFightSkills(self,50);
    HitChance[NPC_TALENT_1H]             = 30;       //¬ладение ќдноручником 
    HitChance[NPC_TALENT_2H]             = 50;       //¬ладение ƒвуручником 
    HitChance[NPC_TALENT_BOW]            = 50;       //”мение обращатьс¤ с Ћуком 
    HitChance[NPC_TALENT_CROSSBOW]       = 10;       //”мение обращатьс¤ с јрбалетом

    Npc_SetTalentSkill(self,NPC_TALENT_1H,1);        // 0-обучен, 1 - боец, 2 - мастер
    Npc_SetTalentSkill(self,NPC_TALENT_2H,1);        // 0-обучен, 1 - боец, 2 - мастер
    Npc_SetTalentSkill(self,NPC_TALENT_BOW,1);       // 0-обучен, 1 - боец, 2 - мастер
    Npc_SetTalentSkill(self,NPC_TALENT_CROSSBOW,0);  // 0-обучен, 1 - боец, 2 - мастер

    // ------ Schdenstyp im Faustkampf ------
    damagetype                          = DAM_BLUNT;

    // ------ senses ------
    senses          =   SENSE_HEAR | SENSE_SEE ;
    senses_range    =   PERC_DIST_ACTIVE_MAX;   //in AI_Constants.d

    // ----- aivar Defaultwerte  ------
    aivar[AIV_MM_FollowTime] = NPC_TIME_FOLLOW;
    //aivar[AIV_FightDistCancel] = FIGHT_DIST_CANCEL;
    //-------- inventory --------
    EquipItem(self,ItMw_2h_Sld_Axe);
    B_CreateAmbientInv(self);
};

func void Set_Relaxed_Visuals()
{   
    Mdl_SetVisual       (self,  "HUMANS.MDS");
    Mdl_ApplyOverlayMds (self,"Humans_Relaxed.mds");
//  Mdl_SetModelFatness(self,0);
//  B_Scale(self);
};

Инстанция получались компактная :-)

instance SLD_826_Soeldner(NPC_SLD_lvl_40_2h)
{
    // ------ NSC ------
    id = 826;
    voice = 6;

    //-------- visuals --------
    B_SetNpcVisual(self,MALE,"Hum_Head_Bald",Face_N_Bullit,BodyTex_N,itar_sld_M);
    Set_Relaxed_Visuals();
    Mdl_SetModelFatness(self,1);

    // ------ TA anmelden ------        
    daily_routine = Rtn_Start_826;
};

func void Rtn_Start_826()
{
    TA_Smalltalk(8,0,22,0,"NW_BIGFARM_HOUSE_08");
    TA_Sleep(22,0,8,0,"NW_BIGFARM_HOUSE_SLD_SLEEP");
};
dosinabox commented 3 years ago
lvl_40_2h

Я бы уровни и владения выносила из прототипа в инстанции. Слишком индивидуальные вещи. На каждый уровень по прототипу, получается?

Kor-Angar commented 3 years ago

На каждый уровень по прототипу, получается?

Скорее по два-три прототипа на фракцию. Сейчас инстанции NPC формируется через B_SetAttributesToChapter(ХХ) и B_SetFightSkills(self,YY). и это совсем неправильно. ввиду того что в начале года я погружался в код Готики 1, то после него инстанции НПС в Готике 2 смотрится совсем-совсем шаблонный. в той же Готики 1 тамплиеры имели условно три шаблона и индивидуальные моменты у именных НПС. в Готике 2 НВ это свелось к условно одному (!) шаблону для наёмников: B_SetAttributesToChapter(4) и B_SetFightSkills(self,50) Для наглядности я вбил наёмников в табличку image

тут видно сразу что у неименных НПС всё одинаково: только доспехи отличаются. хотя вроде как доспех предполагает что НПС более сильный. в принципе на наёмников хватит и одного прототипа, если не делать специализацию на 1р или 2р (сейчас у всех НПС 1р=2р=лук=арбалет что мягко говоря странно).

Я бы уровни и владения выносила из прототипа в инстанции

а зачем их именно выносить? пусть будут в прототипе, если НПС такой весь "индивидуальный", как например Ярвис, то ничего не мешает ему в инстанции скорректировать и уровень и владения арбалетом и шестой круг магии и 1000 маны. ведь прототип на то и прототип? :-)

Kor-Angar commented 3 years ago

попробовал как то расставить НПС в табличке по "качеству"

image

а у тебя в правках Бастер стал супер мечником? :-)

dosinabox commented 3 years ago

а у тебя в правках Бастер стал супер мечником? :-)

Произошло повышение 1р с 30 до 60, потому что он учит до 60.

Kor-Angar commented 3 years ago

Произошло повышение 1р с 30 до 60, потому что он учит до 60.

так проще ему порог обучения было до 30 опустить. Основной учитель Корд, а у Бастера тренируется минимальному уровню, что бы Корд дал голос и согласился учить ГГ.

Бастер и Фестер были самыми слабыми наемниками в игре, что бы низкоуровневый герой мог их побить без проблем. Обучение у Бастера по моему(могу конечно ошибаться) доступно только если его побить.

Сейчас получается что ты этой правкой фактически усложнила вступление в наёмники.

dosinabox commented 3 years ago

Сейчас получается что ты этой правкой фактически усложнила вступление в наёмники.

В таком случае, в следующей версии Бастер будет единственным, кто учит большему (60), чем знает сам (30).

Kor-Angar commented 3 years ago

он будет не единственным :-) такая же ситуация и у Корда и у Рода и у Вульфгара и у Волка и у большинство учителей. Это связано как раз тем что Пираньи расслабились и стали инстанции формировать через B_SetAttributesToChapter(Х) и B_SetFightSkills(self,YY).

что бы решить момент с учителями, нужно решить более глобальную задачу - делать нормальные прототипы для Ментов / Наёмов / Палов / Бандитов. Про как раз это тема :-)

Тогда у Наёмников не будет 6 кругов магии, 1000 мана 50 лука/арбалета/1р/2р :-) а будет как то адекватно осознанно. При этом естественно надо делать это так что бы не нарушился баланс (кол-во опыта, сложность и т.д.), что совсем и совсем не просто, так как требует не только расчётов, но и многочисленных тестов разными игроками. image

Kor-Angar commented 3 years ago

финальные версии такие получились. вроде работают. но возможно чего то в них нехватает :-)

prototype NPC_SLD_lvl_31_1h(C_Npc)
{   
    //-------- primary data --------
    name[0] =                       NAME_Soeldner;
    npctype =                       NPCTYPE_AMBIENT;
    guild =                         GIL_SLD;
    level =                         31;
    flags =                         0;          
    //-------- abilities --------
    attribute[ATR_STRENGTH]  =      125;
    aivar[REAL_STRENGTH]     =      125;
    attribute[ATR_DEXTERITY] =      125;
    aivar[REAL_DEXTERITY]    =      125;
    attribute[ATR_MANA_MAX] =       10;  // срезал до 10
    attribute[ATR_MANA] =           10;  // срезал до 10
    attribute[ATR_HITPOINTS_MAX] =  400;
    attribute[ATR_HITPOINTS] =      400;
    // ------ Grund-Schadensresistenzen: Keine ------
    protection  [PROT_EDGE]             = 0;
    protection  [PROT_BLUNT]            = 0;
    protection  [PROT_POINT]            = 0;
    protection  [PROT_FIRE]             = 0;
    protection  [PROT_MAGIC]            = 0;
    //-------- visuals --------
    // прототипу делать вредно и опасно!!!
    //---------------------------   
    fight_tactic    =   FAI_HUMAN_STRONG;   // MASTER / STRONG / Normal /COWARD

    //-------- Talente -------- 
    B_AddFightSkill      (self, NPC_TALENT_1H,60);
    B_AddFightSkill      (self, NPC_TALENT_2H,30);
    B_AddFightSkill      (self, NPC_TALENT_BOW,60);
    B_AddFightSkill      (self, NPC_TALENT_CROSSBOW,30);

    // ------ Schdenstyp im Faustkampf ------
    damagetype                          = DAM_BLUNT;

    // ------ senses ------
    senses          =   SENSE_HEAR | SENSE_SEE ;
    senses_range    =   PERC_DIST_ACTIVE_MAX;   //in AI_Constants.d

    // ----- aivar Defaultwerte  ------
    aivar[AIV_MM_FollowTime] = NPC_TIME_FOLLOW;
    aivar[AIV_FightDistCancel] = FIGHT_DIST_CANCEL;
    bodyStateInterruptableOverride = FALSE;

    //-------- inventory --------
    EquipItem(self,ItMw_Sld_SteinBrecher);  // одноручная камнедробилка
    EquipItem(self,ItRw_Sld_Bow);           // лук
    CreateInvItems (self, ItRw_Arrow, 50); // стрелы    
//  EquipItem(self,ItMw_1h_Sld_Axe);
//  EquipItem(self,ItMw_1h_Sld_Sword);
    B_CreateAmbientInv(self);
};

prototype NPC_SLD_lvl_31_2h(C_Npc)
{   
    //-------- primary data --------
    name[0] =                       NAME_Soeldner;
    npctype =                       NPCTYPE_AMBIENT;
    guild =                         GIL_SLD;
    level =                         31;
    flags =                         0;          
    //-------- abilities --------
    attribute[ATR_STRENGTH]  =      125;
    aivar[REAL_STRENGTH]     =      125;
    attribute[ATR_DEXTERITY] =      125; 
    aivar[REAL_DEXTERITY]    =      125;
    attribute[ATR_MANA_MAX] =       10;  // срезал до 10
    attribute[ATR_MANA] =           10;  // срезал до 10
    attribute[ATR_HITPOINTS_MAX] =  400;
    attribute[ATR_HITPOINTS] =      400;
    // ------ Grund-Schadensresistenzen: Keine ------
    protection  [PROT_EDGE]             = 0;
    protection  [PROT_BLUNT]            = 0;
    protection  [PROT_POINT]            = 0;
    protection  [PROT_FIRE]             = 0;
    protection  [PROT_MAGIC]            = 0;
    //-------- visuals --------
    // прототипу делать вредно и опасно!!!
    //---------------------------   
    fight_tactic    =   FAI_HUMAN_STRONG;   // MASTER / STRONG / COWARD

    //-------- Talente -------- 
    B_AddFightSkill      (self, NPC_TALENT_1H,30);
    B_AddFightSkill      (self, NPC_TALENT_2H,60);
    B_AddFightSkill      (self, NPC_TALENT_BOW,10);
    B_AddFightSkill      (self, NPC_TALENT_CROSSBOW,30);            

    // ------ Schdenstyp im Faustkampf ------
    damagetype                          = DAM_BLUNT;

    // ------ senses ------
    senses          =   SENSE_HEAR | SENSE_SEE ;
    senses_range    =   PERC_DIST_ACTIVE_MAX;   //in AI_Constants.d

    // ----- aivar Defaultwerte  ------
    aivar[AIV_MM_FollowTime] = NPC_TIME_FOLLOW;
    aivar[AIV_FightDistCancel] = FIGHT_DIST_CANCEL;
    bodyStateInterruptableOverride = FALSE;

    //-------- inventory --------   
//  EquipItem(self,ItMw_2h_Sld_Axe);
    EquipItem(self,ItMw_Sld_Streitaxt); // Двуручный Топор

    B_CreateAmbientInv(self);
};

Инстанция безымянного Наёмника

instance SLD_817_Soeldner(NPC_SLD_lvl_31_1h)
{
    id = 817;
    voice = 6;

    B_SetNpcVisual(self,MALE,"Hum_Head_Bald",Face_L_Tough01,BodyTex_L,itar_sld_M);
    Mdl_SetModelFatness(self,0);
    Set_Relaxed_Visuals();

    daily_routine = Rtn_Start_817;
};

Инстанция уникального Наёмника. По ним пожалуйста сделай замечания.

instance SLD_811_Wolf(NPC_SLD_lvl_31_1h)
{
    name[0] = "Вольф";
    id = 811;
    voice = 8;
    level =                         40;

    npcType = npctype_main;

    //-------- abilities --------
    attribute[ATR_STRENGTH]  =      150;
    aivar[REAL_STRENGTH]     =      150;
    attribute[ATR_DEXTERITY] =      150; // а надо ли столько?
    aivar[REAL_DEXTERITY]    =      150;
    attribute[ATR_HITPOINTS_MAX] =  520;
    attribute[ATR_HITPOINTS] =      520;

    B_AddFightSkill      (self, NPC_TALENT_1H,5);
    B_AddFightSkill      (self, NPC_TALENT_2H,5);
    B_AddFightSkill      (self, NPC_TALENT_BOW,30);
    B_AddFightSkill      (self, NPC_TALENT_CROSSBOW,30);

    B_SetNpcVisual(self,MALE,"Hum_Head_FatBald",Face_N_Wolf,BodyTex_N,ItAr_Sld_m);
    Mdl_SetModelFatness(self,0);
    Set_Relaxed_Visuals();

    Npc_RemoveInvItem(self,ItMw_Sld_SteinBrecher);
    Npc_RemoveInvItem(self,ItMw_Sld_Streitaxt);
    EquipItem(self,ItMw_Nagelkeule2);

    daily_routine = Rtn_Start_811;
};

Тут решил сначала сбросить все навыки на 0, а потом прописать, что бы было явно видно какие параметры. Хотя можно было использовать B_AddFightSkill с отрицательным значением.

instance SLD_802_Buster(NPC_SLD_lvl_31_1h)
{
    name[0] = "Ѕастер";
    id = 802;
    voice = 13;
    npcType = npctype_main;

    //-------- abilities --------
    level =                         18;
    attribute[ATR_STRENGTH]  =      100;
    aivar[REAL_STRENGTH]     =      100;
    attribute[ATR_DEXTERITY] =      100; // а надо ли столько?
    aivar[REAL_DEXTERITY]    =      100;
    attribute[ATR_HITPOINTS_MAX] =  280;
    attribute[ATR_HITPOINTS] =      280;

    HitChance [NPC_TALENT_1H] = 0; //¬ладение ќдноручником 
    HitChance [NPC_TALENT_2H] = 0; //¬ладение ?вуручником 
    HitChance [NPC_TALENT_BOW] = 0; //”мение обращатьс¤ с Ћуком 
    HitChance [NPC_TALENT_CROSSBOW] = 0; //”мение обращатьс¤ с јрбалетом
//  B_AddFightSkill      (self, NPC_TALENT_1H,1);
//  B_AddFightSkill      (self, NPC_TALENT_2H,1);
//  B_AddFightSkill      (self, NPC_TALENT_BOW,1);
//  B_AddFightSkill      (self, NPC_TALENT_CROSSBOW,1);

    B_AddFightSkill      (self, NPC_TALENT_1H,30);
    B_AddFightSkill      (self, NPC_TALENT_2H,10);
    B_AddFightSkill      (self, NPC_TALENT_BOW,30);
    B_AddFightSkill      (self, NPC_TALENT_CROSSBOW,10);

    fight_tactic = FAI_HUMAN_NORMAL;

    Npc_RemoveInvItem(self,ItMw_Sld_SteinBrecher);
    Npc_RemoveInvItem(self,ItMw_Sld_Streitaxt);
    EquipItem(self,ItMw_1h_Sld_Axe);

    B_SetNpcVisual(self,MALE,"Hum_Head_FatBald",Face_N_Drax,BodyTex_N,itar_sld_M);
    Mdl_SetModelFatness(self,0);
    Set_Relaxed_Visuals();

/*
    HitChance [NPC_TALENT_1H] = 60; //¬ладение ќдноручником 
    HitChance [NPC_TALENT_2H] = 30; //¬ладение ƒвуручником 
    HitChance [NPC_TALENT_BOW] = 30; //”мение обращатьс¤ с Ћуком 
    HitChance [NPC_TALENT_CROSSBOW] = 10; //”мение обращатьс¤ с јрбалетом

    Npc_SetTalentSkill(self,NPC_TALENT_1H,1); // 0-обучен, 1 - боец, 2 - мастер
    Npc_SetTalentSkill(self,NPC_TALENT_2H,0); // 0-обучен, 1 - боец, 2 - мастер
    Npc_SetTalentSkill(self,NPC_TALENT_BOW,1); // 0-обучен, 1 - боец, 2 - мастер
    Npc_SetTalentSkill(self,NPC_TALENT_CROSSBOW,0); // 0-обучен, 1 - боец, 2 - мастер
*/  
    daily_routine = Rtn_Start_802;
};

func void Rtn_Start_802()
{
    TA_Smalltalk(7,0,21,0,"NW_BIGFARM_HUT_01");
    TA_Sit_Bench(21,0,7,0,"NW_BIGFARM_HUT_BENCH_02");
};
Kor-Angar commented 3 years ago

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

Kor-Angar commented 3 years ago

в табличку добавил Паладинов https://docs.google.com/spreadsheets/d/1tspBhvi9wPY2TOAkHUQTQgijPHVgt1KjjaMSHiy5WDw вбил исходные данные. сразу бросилось в глаза пару паладинов (219, 267, 260) у которых низкие показатели. может это их забыли поправить и у них параметры остались из Готики 2 классик? как можно это проверить? :-)

так же странно что все паладины 50 уровня вооружены только одноручными мечами :-)

Kor-Angar commented 3 years ago

перенос B_CreateAmbientInv_MIL в прототип https://github.com/Kor-Angar/G2_NotR_Kor_Angar/commit/69a959f6298690265a4a0014d228f7136f52c03f

Kor-Angar commented 3 years ago

prototype Npc_NOV https://github.com/Kor-Angar/G2_NotR_Kor_Angar/commit/097f1bbcd90c8f4f3eb28ea773b96ea062191d18