AmProsius / gothic-1-community-patch

Gothic 1 Community Patch
Other
48 stars 4 forks source link

NPCs guarding gate switches don't reset the switch during their state loop #195

Open pawbuj1981 opened 3 years ago

pawbuj1981 commented 3 years ago

Describe the bug A clear and concise description of what the bug is. NPC don't use gateswitches after fight ! Expected behavior A clear and concise description of what you expected to happen.

Steps to reproduce the issue

  1. Close the gate using switch !
  2. Guard will defeat a hero.
  3. Guard will not use the switch for proper state again !
  4. You have to start dialogue and then after the guard will close/open the gate according to the routine .

Additional context The bug can be easily reproduce at OC gates.

pawbuj1981 commented 3 years ago

That bug was already fixed by Gothic Mod FIx RU , the ZS routine code is below which may be useful , however there are defined funcions which are not present in vanilla scripts.

https://github.com/AmProsius/gothic-1-community-patch/blob/9f4b6ca0724cb9ba635d298726439645dc911b6c/scriptbase/_work/Data/Scripts/Content/Story/ZS/ZS_GuardWheelOpen.d#L6-L47

changed to

func void ZS_GuardWheelOpen()
{
    b_checkpc(self);//new func 
    GuardPerception();
    Npc_PercDisable(self,PERC_OBSERVEINTRUDER);
    Npc_PercDisable(self,PERC_MOVENPC);
    AI_Standup(self);
    AI_StopLookAt(self);
    AI_RemoveWeapon(self);
    self.aivar[AIV_ITEMSTATUS] = FALSE;
    self.aivar[AIV_FOUNDPERSON] = FALSE;
    self.aivar[32] = NOTINPOS;
};

func int ZS_GuardWheelOpen_Loop()
{
    if(self.aivar[32] == ISINPOS)
    {
        if(guardcheckgatestate(self) == 1)//new cond
        {
            AI_Wait(self,1);
            self.aivar[32] = NOTINPOS;
            return LOOP_CONTINUE;
        };
        if(!self.aivar[AIV_FOUNDPERSON])
        {
            if(Npc_GetDistToNpc(self,hero) < 500)
            {
                if(Npc_CanSeeNpc(self,hero) || ((Npc_GetDistToNpc(self,hero) < 200) && !C_BodyStateContains(hero,BS_SNEAK)))
                {
                    B_SmartTurnToNpc(self,hero);
                    self.aivar[AIV_FOUNDPERSON] = TRUE;
                    return LOOP_CONTINUE;
                };
            };
            if(Npc_GetStateTime(self) > self.aivar[21])
            {
                if(self.aivar[AIV_ITEMFREQ] == 1)
                {
                    AI_PlayAni(self,"R_SCRATCHLSHOULDER");
                }
                else if(self.aivar[AIV_ITEMFREQ] == 3)
                {
                    AI_PlayAni(self,"R_SCRATCHEGG");
                }
                else if(self.aivar[AIV_ITEMFREQ] == 5)
                {
                    AI_PlayAni(self,"R_LEGSHAKE");
                }
                else if(self.aivar[AIV_ITEMFREQ] == 7)
                {
                    AI_PlayAni(self,"R_SCRATCHHEAD");
                }
                else if(self.aivar[AIV_ITEMFREQ] == 9)
                {
                    AI_PlayAni(self,"R_SCRATCHRSHOULDER");
                };
                self.aivar[AIV_ITEMFREQ] = Hlp_Random(100) % 10;
                self.aivar[21] = (Hlp_Random(100) % 5) + 5;
                Npc_SetStateTime(self,0);
            };
            AI_Wait(self,1);
            return LOOP_CONTINUE;
        };
        if(Npc_GetDistToNpc(self,hero) > 600)
        {
            self.aivar[AIV_FOUNDPERSON] = FALSE;
            self.aivar[32] = NOTINPOS;
            return LOOP_CONTINUE;
        };
        B_SmartTurnToNpc(self,hero);
        AI_Wait(self,1);
        return LOOP_CONTINUE;
    };
    if(Npc_GetDistToWP(self,self.wp) > 300)
    {
        AI_StopLookAt(self);
        AI_SetWalkMode(self,NPC_WALK);
        AI_GotoWP(self,self.wp);
        return LOOP_CONTINUE;
    };
    if(guardcheckgatestate(self) == 1)
    {
        AI_StopLookAt(self);
        AI_SetWalkMode(self,NPC_WALK);
        if(Wld_IsMobAvailable(self,"VWHEEL"))
        {
            if(Wld_GetMobState(self,"VWHEEL") == 0)
            {
                AI_UseMob(self,"VWHEEL",1);
            };
            AI_Wait(self,0.5);
            AI_UseMob(self,"VWHEEL",0);
            AI_UseMob(self,"VWHEEL",-1);
        }
        else if(Wld_IsMobAvailable(self,"LEVER"))
        {
            if(Wld_GetMobState(self,"LEVER") == 0)
            {
                AI_UseMob(self,"LEVER",1);
            };
            AI_Wait(self,0.5);
            AI_UseMob(self,"LEVER",0);
            AI_UseMob(self,"LEVER",-1);
        };
        AI_GotoWP(self,self.wp);
    };
    AI_StopLookAt(self);
    if(Npc_IsOnFP(self,"VWHEEL"))
    {
        AI_SetWalkMode(self,NPC_WALK);
        AI_GotoFP(self,"VWHEEL");
        AI_AlignToFP(self);
    }
    else if(Wld_IsFPAvailable(self,"VWHEEL"))
    {
        AI_SetWalkMode(self,NPC_WALK);
        AI_GotoFP(self,"VWHEEL");
        AI_AlignToFP(self);
    }
    else
    {
        AI_AlignToWP(self);
    };
    self.aivar[32] = ISINPOS;
    self.aivar[AIV_ITEMFREQ] = Hlp_Random(100) % 10;
    self.aivar[21] = (Hlp_Random(100) % 5) + 5;
    Npc_SetStateTime(self,0);
    return LOOP_CONTINUE;
};

func void ZS_GuardWheelOpen_End()
{
    AI_StopLookAt(self);
    self.aivar[32] = 0;
    self.aivar[AIV_FOUNDPERSON] = 0;
    self.aivar[21] = 0;
    self.aivar[AIV_ITEMSTATUS] = 0;
    self.aivar[AIV_ITEMFREQ] = 0;
};
N1kX94 commented 3 years ago

Я дополню пост оригинальными (недекомпилированными функциями).

Из Gothic Mod Fix Также некоторые возможности в цикле сделаны через циклический триггер в самом патче, также добавлены и задействованы некоторые неиспользуемые aivar, которые как мы знаем, записываются в сохранение к каждому NPC.

// Новый вариант 5.
func void ZS_GuardWheelOpen()
{
    B_CheckPC(self); // функция для проверки прохода через порталы
    GuardPerception();

    Npc_PercDisable(self,PERC_OBSERVEINTRUDER);
    Npc_PercDisable(self,PERC_MOVENPC);

    AI_Standup(self);
    AI_StopLookAt(self);
    AI_RemoveWeapon(self);

    self.aivar[AIV_ItemStatus] = FALSE;
    self.aivar[AIV_FoundPerson] = FALSE;
    self.aivar[AIV_TAPosition] = NOTINPOS;
};

func int ZS_GuardWheelOpen_Loop()
{
    // На позиции.
    if(self.aivar[AIV_TAPosition] == ISINPOS)
    {
        // Контроль состояния ворот. Ворота закрыты -> выход из режима "на позиции" для открытия ворот.
        if(GuardCheckGateState(self) == 1)
        {
            AI_Wait(self,1);
            self.aivar[AIV_TAPosition] = NOTINPOS;
            return LOOP_CONTINUE;
        };

        // Непись не видит ГГ.
        if(!self.aivar[AIV_FoundPerson])
        {
            // Расстояние между неписем и ГГ меньше 5м.
            if(Npc_GetDistToNpc(self,hero) < 500)
            {
                // Непись может видеть ГГ или расстояние меньше 2м и ГГ не крадётся -> поворот к ГГ, переход в режим "вижу ГГ".
                if(Npc_CanSeeNpc(self,hero) || ((Npc_GetDistToNpc(self,hero) < 200) && !C_BodyStateContains(hero,BS_SNEAK)))
                {
                    B_SmartTurnToNpc(self,hero);
                    self.aivar[AIV_FoundPerson] = TRUE;
                    return LOOP_CONTINUE;
                };
            };

            // Проигрывание рандомных анимаций.
            if(Npc_GetStateTime(self) > self.aivar[AIV_StateTime])
            {
                if(self.aivar[AIV_ItemFreq] == 1)
                {
                    AI_PlayAni(self,"R_SCRATCHLSHOULDER");
                }
                else if(self.aivar[AIV_ItemFreq] == 3)
                {
                    AI_PlayAni(self,"R_SCRATCHEGG");
                }
                else if(self.aivar[AIV_ItemFreq] == 5)
                {
                    AI_PlayAni(self,"R_LEGSHAKE");
                }
                else if(self.aivar[AIV_ItemFreq] == 7)
                {
                    AI_PlayAni(self,"R_SCRATCHHEAD");
                }
                else if(self.aivar[AIV_ItemFreq] == 9)
                {
                    AI_PlayAni(self,"R_SCRATCHRSHOULDER");
                };

                self.aivar[AIV_ItemFreq] = Hlp_Random(100)%10;
                self.aivar[AIV_StateTime] = Hlp_Random(100)%5 + 5;
                Npc_SetStateTime(self,0);
            };

            AI_Wait(self,1);
            return LOOP_CONTINUE;
        };

        // Непись видит ГГ, но расстояние между ним и ГГ больше 6м -> выход из состояния "на позиции" для занятия позиции.
        if(Npc_GetDistToNpc(self,hero) > 600)
        {
            self.aivar[AIV_FoundPerson] = FALSE;
            self.aivar[AIV_TAPosition] = NOTINPOS;
            return LOOP_CONTINUE;
        };

        // Поворот к ГГ, ожидание.
        B_SmartTurnToNpc(self,hero);
        AI_Wait(self,1);
        return LOOP_CONTINUE;
    };

    // Расстояние до точки выполнения распорядка превышает 3м -> путь к своему вейпоинту.
    if(Npc_GetDistToWP(self,self.wp) > 300)
    {
        AI_StopLookAt(self);
        AI_SetWalkMode(self,NPC_WALK);
        AI_GotoWP(self,self.wp);
        return LOOP_CONTINUE;
    };

    // Ворота закрыты -> открытие ворот.
    if(GuardCheckGateState(self) == 1) 
    {
        AI_StopLookAt(self);
        AI_SetWalkMode(self,NPC_WALK);

        // Поблизости от непися находится лебёдка -> взаимодействие с лебёдкой.
        if(Wld_IsMobAvailable(self,"VWHEEL"))
        {
            if(Wld_GetMobState(self,"VWHEEL") == 0)
            {
                AI_UseMob(self,"VWHEEL",1);
            };
            AI_Wait(self,0.5);
            AI_UseMob(self,"VWHEEL",0);
            AI_UseMob(self,"VWHEEL",-1);
        }

        // Поблизости от непися находится рычаг -> взаимодействие с рычагом.
        else if(Wld_IsMobAvailable(self,"LEVER"))
        {
            if(Wld_GetMobState(self,"LEVER") == 0)
            {
                AI_UseMob(self,"LEVER",1);
            };
            AI_Wait(self,0.5);
            AI_UseMob(self,"LEVER",0);
            AI_UseMob(self,"LEVER",-1);
        };

        // Путь к своему вейпоинту.
        AI_GotoWP(self,self.wp);
    };

    // Занятие позиции, переход в режим "на позиции".
    AI_StopLookAt(self);
    if(Npc_IsOnFP(self,"VWHEEL"))
    {
        AI_SetWalkMode(self,NPC_WALK);
        AI_GotoFP(self,"VWHEEL");
        AI_AlignToFP(self);
    }
    else if(Wld_IsFPAvailable(self,"VWHEEL"))
    {
        AI_SetWalkMode(self,NPC_WALK);
        AI_GotoFP(self,"VWHEEL");
        AI_AlignToFP(self);
    }
    else
    {
        AI_AlignToWP(self);
    };

    self.aivar[AIV_TAPosition] = ISINPOS;
    self.aivar[AIV_ItemFreq] = Hlp_Random(100)%10;
    self.aivar[AIV_StateTime] = Hlp_Random(100)%5 + 5;
    Npc_SetStateTime(self,0);

    return LOOP_CONTINUE;
};

func void ZS_GuardWheelOpen_End()
{
    AI_StopLookAt(self);
    self.aivar[AIV_TAPosition] = 0;
    self.aivar[AIV_FoundPerson] = 0;
    self.aivar[AIV_StateTime] = 0;
    self.aivar[AIV_ItemStatus] = 0;
    self.aivar[AIV_ItemFreq] = 0;
};
func void B_CheckPC(var C_Npc slf)
{
    var C_Npc portalowner;
    //var int portalguild;
    portalowner = Wld_GetPlayerPortalOwner();
    portalguild = Wld_GetPlayerPortalGuild();
    B_ResetFaceExpression(slf);

    //////////////////////////
    // Попытки обойти баг с двойной экипировкой стрелкового оружия после выхода из спящего режима.
    /*if(Npc_GetDistToNpc(slf,hero) > 3500)
    {
        //PrintScreen("UnequipRangedWeapon",-1,50,"FONT_OLD_10_WHITE.TGA",3);
        PrintScreen(slf.name[0],-1,50,"FONT_OLD_10_WHITE.TGA",3);
        EquippedWeapon = Npc_GetEquippedRangedWeapon(slf);
        if(Hlp_IsValidItem(EquippedWeapon))
        {
            PrintScreen(EquippedWeapon.name,-1,65,"FONT_OLD_10_WHITE.TGA",5);
            //AI_UnequipWeapons(slf);

            EquippedRangedWeapon = Hlp_GetInstanceID(EquippedWeapon);
            if(EquippedWeapon.flags & ITEM_MULTI)
            {
                amount = Npc_HasItems(slf,EquippedRangedWeapon);
                Npc_RemoveInvItems(slf,EquippedRangedWeapon,amount);
                CreateInvItems(slf,EquippedRangedWeapon,amount);
                //amount = Npc_HasItems(slf,EquippedRangedWeapon);
            }
            else
            {
                Npc_RemoveInvItem(slf,EquippedRangedWeapon);
                CreateInvItem(slf,EquippedRangedWeapon);
            };

            //AI_EquipBestMeleeWeapon(slf);
            AI_EquipBestRangedWeapon(slf);
        };
    };*/
    /*if(slf.aivar[AIV_LASTDISTTOWP] == -9999)
    {
        PrintScreen("EquipBestWeapons",-1,53,"FONT_OLD_10_WHITE.TGA",3);
        AI_EquipBestMeleeWeapon(slf);
        AI_EquipBestRangedWeapon(slf);
        slf.aivar[AIV_LASTDISTTOWP] = 0;
    }
    else if(Npc_GetDistToNpc(slf,hero) > 3500)
    {
        if(Npc_HasEquippedRangedWeapon(slf))
        {
            PrintScreen("UnequipWeapons",-1,50,"FONT_OLD_10_WHITE.TGA",3);
            AI_UnequipWeapons(slf);
            AI_UnequipWeapons(slf);
            slf.aivar[AIV_LASTDISTTOWP] = -9999;
            AI_ContinueRoutine(slf);
            return;
        };
    };*/
    //////////////////////////

    // Сброс флага "Бой на арене".
    if(slf.aivar[AIV_ArenaFight] == AF_AFTER)
    {
        slf.aivar[AIV_ArenaFight] = AF_NONE;
    };

    // Свидетель может видеть ГГ.
    if(Npc_CanSeeNpcFreeLOS(slf,hero))
    {
        // Выход, если свидетель был очарован заклинанием "Шарм" или он настроен враждебно по отношению к ГГ.
        if(Npc_RefuseTalk(slf) || (Npc_GetAttitude(slf,hero) == ATT_HOSTILE))
        {
            return;
        };

        // ГГ пребывает в своём облике.
        if(C_NpcIsHuman(hero))
        {
            // Свидетель является собственником помещения, где находится ГГ или гильдия свидетеля имеет дружественные отношения с гильдией-собственником помещения.
            if((slf == portalowner) || (Wld_GetGuildAttitude(slf.guild,portalguild) == ATT_FRIENDLY))
            {
                // Помещение принадлежит Баронам.
                if(portalguild == GIL_EBR)
                {
                    // Свидетель стражник или Барон, ГГ - не маг Огня и не стражник -> старт состояния реакции на проникновение в чужое помещение.
                    if((hero.guild != GIL_GRD) && (hero.guild != GIL_KDF) && ((slf.guild == GIL_GRD) || (slf.guild == GIL_EBR)))
                    {
                        AI_StartState(slf,ZS_ClearRoom,0,"");
                        return;
                    };
                };

                // ГГ не должен находиться в помещении -> старт состояния реакции на проникновение в чужое помещение.
                if((Wld_GetGuildAttitude(hero.guild,portalguild) != ATT_FRIENDLY) && (slf.npcType != npctype_friend) && (Npc_GetAttitude(slf,hero) != ATT_FRIENDLY) && (portalguild != GIL_NONE))
                {
                    AI_StartState(slf,ZS_ClearRoom,0,"");
                    return;
                };
            };
        }

        // ГГ превратился в опасного монстра.
        else if(C_NpcIsDangerousMonster(slf,hero))
        {
            // Дистанция меньше 15м - старт состояния реакции на монстров.
            if(Npc_GetDistToNpc(slf,hero) < HAI_DIST_ASSESS_MONSTER)
            {
                B_FullStop(slf);
                Npc_SetTarget(slf,hero);
                Npc_GetTarget(slf);
                AI_StartState(slf,ZS_AssessMonster,0,"");
                return;
            };
        };
    };
};
// Функция определения состояния ворот, открываемых/закрываемых лебёдкой. Вариант 3.
func int GuardCheckGateState(var C_Npc slf)
{
    // Ворота к месту обмена.
    if(Hlp_StrCmp(slf.wp,"OW_PATH_1_16_C"))
    {
        //slf.aivar[AIV_ItemStatus] = TRUE;
        slf.name[4] = "INTRO_GATE";

        // Охранник лебёдки находится в состоянии ZS_GuardWheelClosed.
        if(Npc_IsInSTate(slf,ZS_GuardWheelClosed))
        {
            Npc_PerceiveAll(slf);

            // Диего находится рядом с воротами -> переход в состояние временного открытия ворот.
            if(Wld_DetectNpc(slf,PC_Thief,NOFUNC,-1))
            {
                if(Npc_GetDistToWP(other,"INTRO_GATE") < 1000)
                {
                    Npc_SetTarget(slf,other);
                    Npc_GetTarget(slf);
                    Npc_ClearAIQueue(slf);
                    AI_StartState(slf,ZS_GuardWheelOpenAndWait,1,"");
                    return GATE_01_STATE;
                };
            };

            // ГГ находится рядом с воротами.
            if(Npc_GetDistToWP(hero,"INTRO_GATE") < 450)
            {
                // Непись готов открыть ворота перед ГГ -> переход в состояние временного открытия ворот.
                if(C_WantToOpenGate(slf,hero))
                {
                    Npc_ClearAIQueue(slf);
                    AI_StartState(slf,ZS_GuardWheelOpenAndWait,1,"");
                    return GATE_01_STATE;
                };
            };
        };

        return GATE_01_STATE;
    }

    // Главные ворота СЛ.
    else if(Hlp_StrCmp(slf.wp,"OCC_MAINGATE_VWHEEL"))
    {
        return GATE_02_STATE;
    }

    // Южные ворота СЛ.
    else if(Hlp_StrCmp(slf.wp,"OCR_NORTHGATE_VWHEEL"))
    {
        return GATE_03_STATE;
    }

    // Ворота замка СЛ.
    else if(Hlp_StrCmp(slf.wp,"OCC_GATE_VWHEEL"))
    {
        return GATE_04_STATE;
    }

    // Внешние ворота НЛ.
    else if(Hlp_StrCmp(slf.wp,"OW_PATH_067_WHEEL"))
    {
        //slf.aivar[AIV_ItemStatus] = TRUE;
        slf.name[4] = "NC_GATE";

        // Охранник лебёдки находится в состоянии ZS_GuardWheelClosed.
        if(Npc_IsInSTate(slf,ZS_GuardWheelClosed))
        {
            // ГГ находится рядом с воротами.
            if(Npc_GetDistToWP(hero,"NC_GATE") < 400)
            {
                // Непись готов открыть ворота перед ГГ -> переход в состояние временного открытия ворот.
                if(C_WantToOpenGate(slf,hero))
                {
                    AI_OutputSVM_Overlay(hero,NULL,"$SC_HEYTURNAROUND");    //Эй, ты!
                    Npc_ClearAIQueue(slf);
                    AI_StartState(slf,ZS_GuardWheelOpenAndWait,1,"");
                    return GATE_01_STATE;
                };
            };
        };

        return GATE_05_STATE;
    }

    // Внутренние ворота НЛ.
    else if(Hlp_StrCmp(slf.wp,"NC_MAINGATE_VWHEEL"))
    {
        return GATE_06_STATE;
    }

    // Ворота СШ.
    else if(Hlp_StrCmp(slf.wp,"OW_OM_ENTRANCE02_WHEEL_USE"))
    {
        return GATE_07_STATE;
    }

    // Ворота подземелья в замке СЛ.
    else if(Hlp_StrCmp(slf.wp,"OCC_MERCS_DOWNSTAIRS_3"))
    {
        return GATE_08_STATE;
    };

    return -1;
};
szapp commented 3 years ago

The essential gist of it is this:

https://github.com/AmProsius/gothic-1-community-patch/blob/9f4b6ca0724cb9ba635d298726439645dc911b6c/scriptbase/_work/Data/Scripts/Content/Story/ZS/ZS_GuardWheelOpen.d#L25-L42

changed to

func int ZS_GuardWheelOpen_Loop()
{
     if (Wld_GetMobState (self,  "VWHEEL") == 1) { 
         AI_UseMob       (self,  "VWHEEL", 0);
         AI_UseMob       (self,  "VWHEEL", -1);
         AI_AlignToWP    (self); 
     }; 

    PrintDebugNpc       (PD_TA_LOOP,"ZS_GuardWheelOpen_Loop");

    if (Npc_GetDistToWP(self,self.wp)>200)
    {
        AI_SetWalkmode  (self,NPC_RUN);
        AI_GotoWP       (self, self.wp);
        return          LOOP_CONTINUE;
    }
    else if (Npc_GetDistToNpc(self,hero) > HAI_DIST_GUARDPASSAGE_ATTENTION)
    {
        AI_AlignToWP    (self);
    };

    AI_Wait             (self,1);
    return              LOOP_CONTINUE;
};

The same will have to be done for the daily routine to guard a closed switch:

https://github.com/AmProsius/gothic-1-community-patch/blob/9f4b6ca0724cb9ba635d298726439645dc911b6c/scriptbase/_work/Data/Scripts/Content/Story/ZS/ZS_GuardWheelClosed.d#L26-L43

changed to

func int ZS_GuardWheelClosed_Loop()
{
    if (Wld_GetMobState (self,  "VWHEEL") == 0) {
        AI_UseMob       (self,  "VWHEEL", 1);
        AI_UseMob       (self,  "VWHEEL", -1);
        AI_AlignToWP    (self);
    };

    PrintDebugNpc       (PD_TA_LOOP,"ZS_GuardWheelClosed_Loop");

    if (Npc_GetDistToWP(self,self.wp)>200)
    {
        AI_SetWalkmode  (self,NPC_RUN);
        AI_GotoWP       (self, self.wp);
        return          LOOP_CONTINUE;
    }
    else if (Npc_GetDistToNpc(self,hero) > HAI_DIST_GUARDPASSAGE_ATTENTION)
    {
        AI_AlignToWP    (self);
    };

    AI_Wait             (self,1);
    return              LOOP_CONTINUE;
};

This can be realized by hooking before the function ZS_GuardWheelOpen_Loop and ZS_GuardWheelClosed_Loop and adding the respective lines before continuing into the original function. Whether that works without problems would have to be checked.

This fix will probably require a manual test (just teleport to a gate that is guarded closed and then to one that is guarded open). An important part is to test this fix with mods that have already addressed that issue!

AmProsius commented 3 years ago

What's with LEVERs? Is someone guarding a lever anyway?

szapp commented 3 years ago

What's with LEVERs? Is someone guarding a lever anyway?

It seems there is no such AI state for levers, only for winches. All the scripts posted before go much beyond the actual fix.

pawbuj1981 commented 2 years ago

As far as I know there is only one mod adressed to this issue : "Gothic Mod Fix" and it is only one mod I would not play together with G1CP. Is possible that G1CP will not run with GMF automatically ? (settings in INI could be changed).

AmProsius commented 2 years ago

As far as I know there is only one mod adressed to this issue : "Gothic Mod Fix" and it is only one mod I would not play together with G1CP. Is possible that G1CP will not run with GMF automatically ? (settings in INI could be changed).

Why wouldn’t you play the Gothic Mod Fix with the G1CP?

pawbuj1981 commented 2 years ago

GMF has fixed stucked gates already. Playing together with G1CP this bug occurs again. I have tested it. I would exclude this one fix for GMF (if it possible to exclude some fixes for some mods/patches).

szapp commented 2 years ago

GMF has fixed stucked gates already. Playing together with G1CP this bug occurs again. I have tested it. I would exclude this one fix for GMF (if it possible to exclude some fixes for some mods/patches).

As in medicine, it may be wiser to treat the cause instead of the symptoms ;)

What I am saying is, it would be better to find out why there might be a conflict, and make it compatible in the G1CP. Disabling fixes in conjunction with certain mods/patches seems like a cheap, unsatisfying (and never ending) way.

I haven’t looked at this specific issue here, but from the top of my head I don’t recall where the G1CP does something about stuck gates. How do you come to the conclusion that the G1CP undoes the fix? Did you test this systematically?

PS: It seems like this potential bug report is not at all related to this here issue ticket. It should be discussed in the correct ticket #193 instead.