Portal-Zone Gothic-Zone Gothic II-Zone Gothic 3-Zone Gothic 4-Zone Modifikationen-Zone Download-Zone Foren-Zone RPG-Zone Almanach-Zone Spirit of Gothic

 

Ergebnis 1 bis 3 von 3
  1. Beiträge anzeigen #1 Zitieren
    Abenteurer Avatar von Senlax
    Registriert seit
    Jan 2021
    Ort
    HH
    Beiträge
    92
     
    Senlax ist offline

    Gothic 1 - Schlüssel wird benötigt (Ohne den richtigen Schlüssel, krieg ich das nie auf)

    Hallo,

    wie ggf. der Titel sagt - frage ich mich wie ich genau diesen Script
    von Gothic 2 in Gothic 1 einbringen kann.

    Wenn man ja in G1 z.B. Türen / Truhen hat, die eig. einen Schlüssel brauchen,
    versucht der Held diese, wenn der Schlüssel nicht vorhanden ist,
    mit einem Dietrich zu öffnen, bis dieser dann abbricht.

    In G2 wird das ja anders geregelt -
    "Ohne den richtigen Schlüssel, krieg ich das nie auf" -
    aber wenn ich mich nicht da nicht so sehr verguckt habe -
    gibt es diese Abfrage nicht in G1 bzw. kann ich diese ja nicht ohne Umwege als Script einbauen oder?

    Falls doch, wie müsste das in etwa aussehen?

    Vielen Dank für jede Art von Hilfen

    PS: Wenn es geht, bitte so schreiben, dass ich das auch "Verstehe"

  2. Beiträge anzeigen #2 Zitieren
    Local Hero
    Registriert seit
    Feb 2017
    Beiträge
    270
     
    F a w k e s ist offline
    Hello Senlax,
    I am using this hooked function _hook_oCMobLockable_CanOpen below.

    Function is replacing original G1 engine function oCMobLockable::CanOpen and does following:
    • If players NPC_TALENT_PICKLOCK level is 0 then he can't interact with locked doors/chests.
    • If oCMobLockable requires special key only and he does not have it then he can't interact with locked doors/chests (won't break any picklocks).
    • If players NPC_TALENT_PICKLOCK level > 0 then
      • If player does not have pickLocks he can't use interact with locked doors/chests.

    • If player has key that can open doors/chests then he can do so without NPC_TALENT_PICKLOCK.
    • PickLock failrate (breaking) is based on Players dexterity. Higher it is lower the chance to break picklocks is. (by default minimum failrate is 10%)

    It is not perfect though - seems like this function is called in a proximity to oCMobLockable (not on an event of interaction) therefore I can't call PLAYER_MOB_MISSING_KEY, PLAYER_MOB_MISSING_LOCKPICK, PLAYER_MOB_MISSING_KEY_OR_LOCKPICK or PLAYER_MOB_NEVER_OPEN in a fashion as it is done in G2A. These functions would be called over and over again. Therefore they're commented out. If someone has an idea on how to fix this - let me know

    In order to use it call function G1_CanOpen_Init from your Init_Global() function. (both LeGo and Ikarus script-packages are required)
    Code:
    /*
    *    Returns no if items based on instance name
    *    var int ore; ore = NPC_HasItemInstanceName (hero, "itmiNugget");
    */
    func int NPC_HasItemInstanceName (var int slfInstance, var string instanceName) {
        var C_NPC slf; slf = Hlp_GetNPC (slfInstance);
        if (!Hlp_IsValidNPC (slf)) { return 0; };
    
        var int symbID; symbID = MEM_GetSymbolIndex (instanceName);
        if (symbID > 0) && (symbID < currSymbolTableLength) {
            if (NPC_GetInvItem (slf, symbID)) {
                return NPC_HasItems (slf, Hlp_GetInstanceID (item));
            };
        };
        
        return FALSE;
    };
    
    //0x006827C0 public: int __thiscall oCMobLockable::CanOpen(class oCNpc *) 
    const int oCMobLockable__CanOpen = 6825920;
    
    func void _hook_oCMobLockable_CanOpen () {
        //Safety checks
        if (!Hlp_Is_oCMobLockable (ECX)) {
            EAX = FALSE;
            return;
        };
    
        //NPC is first parameter
        var int slfPtr; slfPtr = MEM_ReadInt (ESP + 4);
        if (!Hlp_Is_oCNpc (slfPtr)) {
            EAX = FALSE;
            return;
        };
    
        var oCNPC slf; slf = _^ (slfPtr);
    
        //We don't need to check if it is non player
        if (!NPC_IsPlayer (slf)) {
            EAX = TRUE;
            return;
        };
    
        //We need one more C_NPC type variable for NPC_GetTalentSkil & Npc_SetTalentValue :-/
        var C_NPC npc; npc = Hlp_GetNPC (slf);
    
        //By default let's assume we can open this mob
        var int canOpen; canOpen = TRUE;
        
        var oCMobLockable mob; mob = _^ (ECX);
    
        var int lockType; lockType = 0;
    
        const int requiresPickLock            = 1;
        const int requiresSpecialKey            = 2;
        const int requiresBothSpecialKeyAndPickLock    = 3;
    
        //Determine if we really can open this mob
        if (mob.bitfield & oCMobLockable_bitfield_locked) {
            //No PickLocks required, only special key
            if (STR_Len (mob.pickLockStr) == 0) {
                //No PickLocks, no key ?
                if (STR_Len (mob.keyInstance) == 0) {
                    //Unlock - this is incorrectly flagged as locked
                    mob.bitfield = (mob.bitfield & ~ oCMobLockable_bitfield_locked);
                } else {
                    lockType = requiresSpecialKey;
    
                    //Do we have key?
                    if (!NPC_HasItemInstanceName (slf, mob.keyInstance)) {
                        //MEM_Call (PLAYER_MOB_MISSING_KEY);
                        canOpen = FALSE;
                    };
                };
            } else {
            //Can be PickLocked
                //Can be opened only with pickLocks
                if (STR_Len (mob.keyInstance) == 0) {
                    lockType = requiresPickLock;
    
                    //No picklocks
                    if (!NPC_HasItems (slf, ItKeLockPick)) {
                        //MEM_Call (PLAYER_MOB_MISSING_LOCKPICK);
                        canOpen = FALSE;
                    };
                } else {
                //Can be opened with both special key and pickLocks
                    lockType = requiresBothSpecialKeyAndPickLock;
    
                    if (!NPC_HasItemInstanceName (slf, mob.keyInstance)) {
                        //Do we have LockPicks ?
                        if (!NPC_HasItems (slf, ItKeLockPick)) {
                            //MEM_Call (PLAYER_MOB_MISSING_KEY_OR_LOCKPICK);
                            canOpen = FALSE;
                        };
                    };
                };
            };
    
            //If we need to picklock this one - check if we know ho to do so !
            if (lockType == requiresPickLock) {
                //Do we need to learn anything ?
                if (NPC_GetTalentSkill (npc, NPC_TALENT_PICKLOCK) == 0) {
                    //MEM_Call (PLAYER_MOB_NEVER_OPEN);
                    canOpen = FALSE;
                };
            } else
            //If this one can be picklocked ...
            if (lockType == requiresBothSpecialKeyAndPickLock) {
                //And we are not able to open it ... (as we don't have a key)
                if (canOpen == FALSE) {
                    //Do we need to learn anything ?
                    if (NPC_GetTalentSkill (npc, NPC_TALENT_PICKLOCK) == 0) {
                        //MEM_Call (PLAYER_MOB_NEVER_OPEN);
                    };
                };
            };
        };
    
        //Recalculate skill level - based on dexterity
        var int failRate; failRate = 100 - npc.attribute [ATR_DEXTERITY];
    
        //Default 10% chance to break PickLock (even if dexterity > 90)
        if (failRate < 10) {
            failRate = 10;
        };
    
        Npc_SetTalentValue (npc, NPC_TALENT_PICKLOCK, failRate);
    
        EAX = canOpen;
    };
    
    func void G1_CanOpen_Init () {
        const int once = 0;
        if (!once) {
            ReplaceEngineFunc (oCMobLockable__CanOpen, 1, "_hook_oCMobLockable_CanOpen");
            once = 1;
        };
    };
    edit: 2021-02-18 function NPC_HasItemInstanceName fixed.
    Geändert von F a w k e s (18.02.2021 um 00:00 Uhr) Grund: fixing NPC_HasItemInstanceName

  3. Beiträge anzeigen #3 Zitieren
    Abenteurer Avatar von Senlax
    Registriert seit
    Jan 2021
    Ort
    HH
    Beiträge
    92
     
    Senlax ist offline
    Zitat Zitat von F a w k e s Beitrag anzeigen
    Hello Senlax,
    I am using this hooked function _hook_oCMobLockable_CanOpen below.

    Function is replacing original G1 engine function oCMobLockable::CanOpen and does following:
    • If players NPC_TALENT_PICKLOCK level is 0 then he can't interact with locked doors/chests.
    • If oCMobLockable requires special key only and he does not have it then he can't interact with locked doors/chests (won't break any picklocks).
    • If players NPC_TALENT_PICKLOCK level > 0 then
      • If player does not have pickLocks he can't use interact with locked doors/chests.

    • If player has key that can open doors/chests then he can do so without NPC_TALENT_PICKLOCK.
    • PickLock failrate (breaking) is based on Players dexterity. Higher it is lower the chance to break picklocks is. (by default minimum failrate is 10%)

    It is not perfect though - seems like this function is called in a proximity to oCMobLockable (not on an event of interaction) therefore I can't call PLAYER_MOB_MISSING_KEY, PLAYER_MOB_MISSING_LOCKPICK, PLAYER_MOB_MISSING_KEY_OR_LOCKPICK or PLAYER_MOB_NEVER_OPEN in a fashion as it is done in G2A. These functions would be called over and over again. Therefore they're commented out. If someone has an idea on how to fix this - let me know

    In order to use it call function G1_CanOpen_Init from your Init_Global() function. (both LeGo and Ikarus script-packages are required)
    Code:
    /*
    *    Returns no if items based on instance name
    *    var int ore; ore = NPC_HasItemInstanceName (hero, "itmiNugget");
    */
    func int NPC_HasItemInstanceName (var int slfInstance, var string instanceName) {
        var C_NPC slf; slf = Hlp_GetNPC (slfInstance);
        if (!Hlp_IsValidNPC (slf)) { return 0; };
    
        var int symbID; symbID = MEM_GetSymbolIndex (instanceName);
        if (symbID > 0) && (symbID < currSymbolTableLength) {
            if (NPC_GetInvItem (slf, symbID)) {
                return NPC_HasItems (slf, item);
            };
        };
        
        return FALSE;
    };
    
    //0x006827C0 public: int __thiscall oCMobLockable::CanOpen(class oCNpc *) 
    const int oCMobLockable__CanOpen = 6825920;
    
    func void _hook_oCMobLockable_CanOpen () {
        //Safety checks
        if (!Hlp_Is_oCMobLockable (ECX)) {
            EAX = FALSE;
            return;
        };
    
        //NPC is first parameter
        var int slfPtr; slfPtr = MEM_ReadInt (ESP + 4);
        if (!Hlp_Is_oCNpc (slfPtr)) {
            EAX = FALSE;
            return;
        };
    
        var oCNPC slf; slf = _^ (slfPtr);
    
        //We don't need to check if it is non player
        if (!NPC_IsPlayer (slf)) {
            EAX = TRUE;
            return;
        };
    
        //We need one more C_NPC type variable for NPC_GetTalentSkil & Npc_SetTalentValue :-/
        var C_NPC npc; npc = Hlp_GetNPC (slf);
    
        //By default let's assume we can open this mob
        var int canOpen; canOpen = TRUE;
        
        var oCMobLockable mob; mob = _^ (ECX);
    
        var int lockType; lockType = 0;
    
        const int requiresPickLock            = 1;
        const int requiresSpecialKey            = 2;
        const int requiresBothSpecialKeyAndPickLock    = 3;
    
        //Determine if we really can open this mob
        if (mob.bitfield & oCMobLockable_bitfield_locked) {
            //No PickLocks required, only special key
            if (STR_Len (mob.pickLockStr) == 0) {
                //No PickLocks, no key ?
                if (STR_Len (mob.keyInstance) == 0) {
                    //Unlock - this is incorrectly flagged as locked
                    mob.bitfield = (mob.bitfield & ~ oCMobLockable_bitfield_locked);
                } else {
                    lockType = requiresSpecialKey;
    
                    //Do we have key?
                    if (!NPC_HasItemInstanceName (slf, mob.keyInstance)) {
                        //MEM_Call (PLAYER_MOB_MISSING_KEY);
                        canOpen = FALSE;
                    };
                };
            } else {
            //Can be PickLocked
                //Can be opened only with pickLocks
                if (STR_Len (mob.keyInstance) == 0) {
                    lockType = requiresPickLock;
    
                    //No picklocks
                    if (!NPC_HasItems (slf, ItKeLockPick)) {
                        //MEM_Call (PLAYER_MOB_MISSING_LOCKPICK);
                        canOpen = FALSE;
                    };
                } else {
                //Can be opened with both special key and pickLocks
                    lockType = requiresBothSpecialKeyAndPickLock;
    
                    if (!NPC_HasItemInstanceName (slf, mob.keyInstance)) {
                        //Do we have LockPicks ?
                        if (!NPC_HasItems (slf, ItKeLockPick)) {
                            //MEM_Call (PLAYER_MOB_MISSING_KEY_OR_LOCKPICK);
                            canOpen = FALSE;
                        };
                    };
                };
            };
    
            //If we need to picklock this one - check if we know ho to do so !
            if (lockType == requiresPickLock) {
                //Do we need to learn anything ?
                if (NPC_GetTalentSkill (npc, NPC_TALENT_PICKLOCK) == 0) {
                    //MEM_Call (PLAYER_MOB_NEVER_OPEN);
                    canOpen = FALSE;
                };
            } else
            //If this one can be picklocked ...
            if (lockType == requiresBothSpecialKeyAndPickLock) {
                //And we are not able to open it ... (as we don't have a key)
                if (canOpen == FALSE) {
                    //Do we need to learn anything ?
                    if (NPC_GetTalentSkill (npc, NPC_TALENT_PICKLOCK) == 0) {
                        //MEM_Call (PLAYER_MOB_NEVER_OPEN);
                    };
                };
            };
        };
    
        //Recalculate skill level - based on dexterity
        var int failRate; failRate = 100 - npc.attribute [ATR_DEXTERITY];
    
        //Default 10% chance to break PickLock (even if dexterity > 90)
        if (failRate < 10) {
            failRate = 10;
        };
    
        Npc_SetTalentValue (npc, NPC_TALENT_PICKLOCK, failRate);
    
        EAX = canOpen;
    };
    
    func void G1_CanOpen_Init () {
        const int once = 0;
        if (!once) {
            ReplaceEngineFunc (oCMobLockable__CanOpen, 1, "_hook_oCMobLockable_CanOpen");
            once = 1;
        };
    };
    This is PERFECT!

    Thank you F a w k e s!
    It works very well and it is really, really awesome!

    Thanks for your help

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
Impressum | Link Us | intern
World of Gothic © by World of Gothic Team
Gothic, Gothic 2 & Gothic 3 are © by Piranha Bytes & Egmont Interactive & JoWooD Productions AG, all rights reserved worldwide