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

 

Seite 5 von 10 « Erste 123456789 ... Letzte »
Ergebnis 81 bis 100 von 195
  1. Beiträge anzeigen #81 Zitieren
    Ehrengarde Avatar von mud-freak
    Registriert seit
    Dec 2005
    Beiträge
    2.199
     
    mud-freak ist offline
    Zitat Zitat von Lehona Beitrag anzeigen
    For a bug to occur without the '+', the following conditions are necessary:
    A function f that returns a variable directly, not a computation (return x; vs return x+1)
    And a caller has to use f in a way such that it is called twice before either return value is used in a computation. Essentially:

    Code:
    func int thingy(var int x) {
        return x;
    };
    
    func int bug() {
        // Prints 8, not 7
        print(IntToString(thingy(3)+thingy(4)));
    };
    Changing thingy to 'return +x;' instead fixes the bug.
    Danke für das Beispiel. Jetzt ist mir auch wieder eingefallen, wo das Problem im Zusammenhang mit HookEngineF und MEMINT_SwitchG1G2 auftrat:
    Code:
    HookEngineF(MEMINT_SwitchG1G2(addrG1, addrG2), MEMINT_SwitchG1G2(5, 7), someFunction);

  2. Beiträge anzeigen #82 Zitieren
    Serima Avatar von Fisk2033
    Registriert seit
    Dec 2010
    Ort
    Dresden
    Beiträge
    5.803
     
    Fisk2033 ist offline
    I want to use Fawkes "MoveVobs"-Script in Gothic 2. How I can define "oCMobLadder_vtbl"? Maybe its my mistake but I cant find it anywhere (except Ikarus_Const_G1.d).

  3. Beiträge anzeigen #83 Zitieren
    Local Hero
    Registriert seit
    Feb 2017
    Beiträge
    270
     
    F a w k e s ist offline
    Zitat Zitat von Fisk2033 Beitrag anzeigen
    I want to use Fawkes "MoveVobs"-Script in Gothic 2. How I can define "oCMobLadder_vtbl"? Maybe its my mistake but I cant find it anywhere (except Ikarus_Const_G1.d).
    This should be constant for G2A:
    Code:
    //0x0083CF2C const oCMobLadder::`vftable'
    const int oCMobLadder_vtbl = 8638252;

  4. Beiträge anzeigen #84 Zitieren
    Local Hero
    Registriert seit
    Feb 2017
    Beiträge
    270
     
    F a w k e s ist offline

    G1 In-game object moving v2

    Hello folks,
    Slightly improved version:
    Press '[' to activate select mode.

    Select mode:
    Use left/right arrows to select objects you want to move/rotate.
    Press '[' to confirm selection of the object - this will activate Transform mode.
    Press ']' to cancel select mode.

    Transform mode:
    Move around hero to move around object.
    Press 'E' to adjust elevation: use up/down arrows to adjust vertical position of object
    Press 'X', 'Y', or 'Z' to activate rotation mode.
    Press '[' to stop interaction.
    Press ']' to align to surface.

    Rotation mode:
    Use arrow keys to adjust rotation of respective axis.

    [Video]

    Here is code if you would be interested:

    Required:
    Ikarus 1.2.1
    Function NPC_CanSee & AI_TurnToVobPtr from:
    https://forum.worldofplayers.de/foru...1#post26640112

    Function SetVobToFloor from Scriptbin\InsertAnything:
    https://forum.worldofplayers.de/foru...1#post25712257

    Functions from Scriptbin\NPCVobList.d:
    https://forum.worldofplayers.de/foru...1#post26052199

    Functions from Scriptbin\gameKeyEvents.d
    https://forum.worldofplayers.de/foru...1#post26055992

    Other variables and functions which are required:
    Code:
    //--- vob Transport global variables & constants
    
    const int vobTRange                     = 300;
    
    var int vobTPtr;
    var int vobTVobList;
    
    var int vobTMode;
        const int cvobTMode_Disabled        = 0;
        const int cvobTMode_Init            = 1;
        
        const int cvobTMode_Select          = 2;
        const int cvobTMode_Select_Next     = 3;
        const int cvobTMode_Select_Previous = 4;
        const int cvobTMode_Select_Confirm  = 5;
        
        const int cvobTMode_Moving          = 6;
        const int cvobTMode_Done            = 7;
    
    var int vobTModeAlignToFloor;
    var int vobTCollBits;
    
    var int vobTMovementSpeed;
    var int vobTModeXYZE;
        const int cvobTRotationMode_0    = 0;
        const int cvobTRotationMode_X    = 1;
        const int cvobTRotationMode_Y    = 2;
        const int cvobTRotationMode_Z    = 3;
        const int cvobTRotationMode_E    = 4;    //Elevation
    
    var int vobTRotX;
    var int vobTRotY;
    var int vobTRotZ;
    var int vobTElevation;
    
    /***
        Hero_Lock will freeze player in place (he will not move)
    ***/
    FUNC VOID Hero_Lock () {
        NPC_ClearAIQueue (hero);
    
        var oCNpc her;
        her = Hlp_GetNpc (hero);
        her._zCVob_bitfield[2] = (her._zCVob_bitfield[2] & ~ zCVob_bitfield2_sleepingMode) | 0;
    };
    
    /***
        Hero_UnLock will unfreeze player
    ***/
    FUNC VOID Hero_UnLock () {
        NPC_ClearAIQueue (hero);
    
        var oCNpc her;
        her = Hlp_GetNpc (hero);
        her._zCVob_bitfield[2] = (her._zCVob_bitfield[2] & ~ zCVob_bitfield2_sleepingMode) | 1;
    };
    
    /***
        Will draw BBox3D on Vob
    ***/
    FUNC VOID Vob_SetDrawBBox3D (var int vobPtr, var int onOff) {
        //00645030  .text     Debug data           ?SetDrawBBox3D@zCVob@@QAEXH@Z
        const int zCVob__SetDrawBBox3D_G1 = 6574128;
    
        //0x006CFFE0 public: void __thiscall zCVob::SetDrawBBox3D(int)
        const int zCVob__SetDrawBBox3D_G2 = 7143392;
        
        if (!vobPtr) { return; };
    
    
        CALL_IntParam (onOff);
        CALL__thiscall (vobPtr, MEMINT_SwitchG1G2 (zCVob__SetDrawBBox3D_G1, zCVob__SetDrawBBox3D_G2));
    };
    
    /***
        VobGetCollBits will return collision bitfield values
    ***/
    FUNC INT VobGetCollBits (var int vobPtr) {
        if (!vobPtr) { return 0; };
        var int collBits; collBits = (zCVob_bitfield0_collDetectionStatic + zCVob_bitfield0_collDetectionDynamic);
        var zCVob vob; vob = MEM_PtrToInst (vobPtr);
        return (vob.bitfield[0] & (collBits));
    };
    
    /***
        VobRemoveCollBits - will remove collisions based on input bitfield values in collBits
    ***/
    FUNC VOID VobRemoveCollBits (var int vobPtr, var int collBits) {
        if (!vobPtr) { return; };
        var zCVob vob; vob = MEM_PtrToInst (vobPtr);
        vob.bitfield[0] = vob.bitfield[0] & ~ (collBits);
    };
    
    /***
        VobRestoreCollBits - will apply collisions based on input bitfield values in collBits
    ***/
    FUNC VOID VobRestoreCollBits (var int vobPtr, var int collBits) {
        if (!vobPtr) { return; };
        var zCVob vob; vob = MEM_PtrToInst (vobPtr);
        vob.bitfield[0] = vob.bitfield[0] | (collBits);
    };
    
    /***
        Rotates vob on its X axis
    ***/
    func void TRF_RotateLocalX(var zCVob obj, var int x) {
        //005EE1A0  .text     Debug data           ?RotateLocalX@zCVob@@QAEXM@Z
        const int zCVob__RotateLocalX_G1 = 6218144;
    
        //0x0061B6B0 public: void __thiscall zCVob::RotateLocalX(float)
        const int zCVob__RotateLocalX_G2 = 6403760;
        
            CALL_FloatParam(x);
        CALL__thiscall(MEM_InstToPtr(obj), MEMINT_SwitchG1G2 (zCVob__RotateLocalX_G1, zCVob__RotateLocalX_G2));
    };
    
    /***
        Rotates vob on its Y axis
    ***/
    func void TRF_RotateLocalY(var zCVob obj, var int x) {
        //005EE210  .text     Debug data           ?RotateLocalY@zCVob@@QAEXM@Z
        const int zCVob__RotateLocalY_G1 = 6218256;
        
        //0x0061B720 public: void __thiscall zCVob::RotateLocalY(float)
        const int zCVob__RotateLocalY_G2 = 6403872;
        
            CALL_FloatParam(x);
        CALL__thiscall(MEM_InstToPtr(obj), MEMINT_SwitchG1G2 (zCVob__RotateLocalY_G1, zCVob__RotateLocalY_G2));
    };
    
    /***
        Rotates vob on its Z axis
    ***/
    func void TRF_RotateLocalZ(var zCVob obj, var int x) {
        //005EE280  .text     Debug data           ?RotateLocalZ@zCVob@@QAEXM@Z
        const int zCVob__RotateLocalZ_G1 = 6218368;
        
        //0x0061B790 public: void __thiscall zCVob::RotateLocalZ(float)
        const int zCVob__RotateLocalZ_G2 = 6403984;
        
        CALL_FloatParam(x);
        CALL__thiscall(MEM_InstToPtr(obj), MEMINT_SwitchG1G2 (zCVob__RotateLocalZ_G1, zCVob__RotateLocalZ_G2));
    };
    
    /***
        Rotates vob on its X Y Z axes
    ***/
    func void TRF_RotateLocal(var zCVob obj, var int x, var int y, var int z) {
            TRF_RotateLocalX(obj, x);
            TRF_RotateLocalY(obj, y);
            TRF_RotateLocalZ(obj, z);
    };
    
    //http://themodders.org/index.php?topic=10383.msg1256794#msg1256794
    
    func void Vob_Move(var int ptr, var int x, var int y, var int z) {
        const int zCVob__Move_G1 = 6217184; //0x5EDDE0
        const int zCVob__Move_G2 = 6402784; //0x61B2E0
        
        CALL_FloatParam (x);
        CALL_FloatParam (y);
        CALL_FloatParam (z);
    
        CALL__thiscall (ptr, MEMINT_SwitchG1G2 (zCVob__Move_G1, zCVob__Move_G2));
    };
    
    func void MoveVobInFront(var int slfInstance, var int vobPtr) {
        var zCVob slf; slf = Hlp_GetNPC (slfInstance);
        var zCVob vob; vob = _^ (vobPtr);
        
        //Move vob to NPC X Y Z coordinates
        Vob.trafoObjToWorld [03] = slf.trafoObjToWorld [03];
        Vob.trafoObjToWorld [07] = slf.trafoObjToWorld [07];
        Vob.trafoObjToWorld [11] = slf.trafoObjToWorld [11];
        
        //Adjust 'elevation'
        Vob.trafoObjToWorld [07] = addf (Vob.trafoObjToWorld [07], mkf (vobTElevation));
    
        //Keep vob data (rotation)
        MEM_CopyBytes(_@(vob) + 60, vobPtr + 60, 64);
    
        // Vob vor den Helden setzen
        var int delta;
        delta = mkf(150);
    
        Vob_Move (vobPtr, mulf (slf.trafoObjToWorld[10], delta), mulf (slf.trafoObjToWorld[6], delta), mulf (slf.trafoObjToWorld[2], delta));
    };
    FrameHandler_VobTransport function - has to be called every frame:
    Code:
    FUNC VOID FrameHandler_vobTransport ()
    {
        //Loop through all nearby vobs
        var int i;
        var int loop;
        
        var int vobPtr;
        
        //Identification of object which should be moved around
        if (vobTMode == cvobTMode_Init) {
            //Safety-check
            if (Hlp_IsValidNPC (hero)) {
                var oCNPC her;
                her = Hlp_GetNPC (hero);
                
                var zCVob vob;
    
                //Reset
                vobTPtr = 0;
                
                //Is there anything in hero's focus ?
                if (her.focus_vob) {
                    //Move around following objects
                    if (Hlp_Is_oCMob (her.focus_vob))
                    || (Hlp_Is_oCMobInter (her.focus_vob))
                    || (Hlp_Is_oCMobFire (her.focus_vob))
                    || (Hlp_Is_oCMobLockable (her.focus_vob))
                    || (Hlp_Is_oCMobContainer (her.focus_vob))
                    || (Hlp_Is_oCMobDoor (her.focus_vob))
                    || (Hlp_Is_oCMobLadder (her.focus_vob))
                    {
                        //Get pointer of focus_vob
                        vobTPtr = her.focus_vob;
                        
                        //Change vobTMode
                        vobTMode = cvobTMode_Select;
                    };
                };
    
                //Detect all nearby objects
                NPC_ClearVobList (hero);
                NPC_CreateVobList (hero, vobTRange);
                
                vobTVobList = her.vobList_array;
    
                //If there was nothing in focus - find an object
                if (!vobTPtr) {
                    MEM_InitLabels ();
    
                    i = 0;
                    loop = MEM_StackPos.position;
                    
                    if (her.vobList_numInArray > 0) {
                        vobPtr = MEM_ReadIntArray (her.vobList_array, i);
                        
                        if (Hlp_Is_oCMob (vobPtr))
                        || (Hlp_Is_oCMobInter (vobPtr))
                        || (Hlp_Is_oCMobFire (vobPtr))
                        || (Hlp_Is_oCMobLockable (vobPtr))
                        || (Hlp_Is_oCMobContainer (vobPtr))
                        || (Hlp_Is_oCMobDoor (vobPtr))
                        || (Hlp_Is_oCMobLadder (vobPtr))
    
                        //zCVob
                        || (MEM_ReadInt (vobPtr) == zCVob_vtbl)
                        {
                            //Is this vob in front of player - can player see it?
                            if (NPC_CanSee (hero, vobPtr, 0)) {
                                //Get pointer of moved object
                                vobTPtr = vobPtr;
                                
                                //Change vobTMode
                                vobTMode = cvobTMode_Select;
                            };
                        };
                        
                        //If vobTMode was not changed ... continue in loop (or exit)
                        if (vobTMode == cvobTMode_Init) {
                            i += 1;
                            if (i < her.vobList_numInArray) {
                                MEM_StackPos.position = loop;
                            };
                        };
                    };
                };
            };
            
            //If vobTMode was not changed ... then there was no object detected - disable vobTMode
            if (vobTMode == cvobTMode_Init) {
                vobTMode = cvobTMode_Disabled;
            } else {
                //Select mode - draw BBox and lock hero
                Vob_SetDrawBBox3D (vobTPtr, 1);
                Hero_Lock ();
            };
        };
    
        if (vobTMode == cvobTMode_Select_Next) {
            //loop through vob list - select next in the list
    
            var int flg_Next; flg_Next = FALSE;
            
            /*
            NPC_ClearVobList (hero);
            NPC_CreateVobList (hero, vobTRange);
            */
            her.vobList_array = vobTVobList;
            
            MEM_InitLabels ();
            
            i = 0;
            loop = MEM_StackPos.position;
            
            if (her.vobList_numInArray > 0) {
                vobPtr = MEM_ReadIntArray (her.vobList_array, i);
                
                if (Hlp_Is_oCMob (vobPtr))
                || (Hlp_Is_oCMobInter (vobPtr))
                || (Hlp_Is_oCMobFire (vobPtr))
                || (Hlp_Is_oCMobLockable (vobPtr))
                || (Hlp_Is_oCMobContainer (vobPtr))
                || (Hlp_Is_oCMobDoor (vobPtr))
                || (Hlp_Is_oCMobLadder (vobPtr))
    
                //zCVob
                || (MEM_ReadInt (vobPtr) == zCVob_vtbl)
                {
                    if (flg_Next == FALSE) {
                        if (vobTPtr == vobPtr) {
                            flg_Next = TRUE;
                        };
                    } else {
                        //Remove BBox from last vobPtr
                        Vob_SetDrawBBox3D (vobTPtr, 0);
                        
                        //Get pointer of moved object
                        vobTPtr = vobPtr;
                        
                        //Add Bbox to next vobPtr
                        Vob_SetDrawBBox3D (vobTPtr, 1);
    
                        NPC_ClearAIQueue (hero);
                        AI_TurnToVobPtr (hero, vobTPtr);
    
                        //Change vobTMode
                        vobTMode = cvobTMode_Select;
                    };
                };
                
                //If vobTMode was not changed ... continue in loop (or exit)
                if (vobTMode == cvobTMode_Select_Next) {
                    i += 1;
                    if (i < her.vobList_numInArray) {
                        MEM_StackPos.position = loop;
                    };
                    
                    vobTMode = cvobTMode_Select;
                };
            };
        };
    
        if (vobTMode == cvobTMode_Select_Previous) {
            //loop through vob list - select previous in the list
            var int flg_Previous; flg_Previous = FALSE;
    
            //NPC_ClearVobList (hero);
            //NPC_CreateVobList (hero, vobTRange);
    
            her.vobList_array = vobTVobList;
            
            MEM_InitLabels ();
            
            i = 0;
            loop = MEM_StackPos.position;
            
            if (her.vobList_numInArray > 0) {
                vobPtr = MEM_ReadIntArray (her.vobList_array, i);
                
                if (Hlp_Is_oCMob (vobPtr))
                || (Hlp_Is_oCMobInter (vobPtr))
                || (Hlp_Is_oCMobFire (vobPtr))
                || (Hlp_Is_oCMobLockable (vobPtr))
                || (Hlp_Is_oCMobContainer (vobPtr))
                || (Hlp_Is_oCMobDoor (vobPtr))
                || (Hlp_Is_oCMobLadder (vobPtr))
    
                //zCVob
                || (MEM_ReadInt (vobPtr) == zCVob_vtbl)
                {
                    if (flg_Previous == FALSE) {
                        if (vobTPtr == vobPtr) {
                            flg_Previous = TRUE;
                        };
                    } else {
                        //Remove Bbox from last vobPtr
                        Vob_SetDrawBBox3D (vobTPtr, 0);
                        
                        //Get pointer of moved object
                        vobTPtr = vobPtr;
                        
                        //Add Bbox to previous vobPtr
                        Vob_SetDrawBBox3D (vobTPtr, 1);
                        
                        NPC_ClearAIQueue (hero);
                        AI_TurnToVobPtr (hero, vobTPtr);
    
                        //Change vobTMode
                        vobTMode = cvobTMode_Select;
                    };
                };
                
                //If vobTMode was not changed ... continue in loop (or exit)
                if (vobTMode == cvobTMode_Select_Previous) {
                    if (flg_Previous == FALSE) {
                        i += 1;
                        if (i < her.vobList_numInArray) {
                            MEM_StackPos.position = loop;
                        };
                    } else {
                        if (i > 0) {
                            i -= 1;
                        };
                        
                        MEM_StackPos.position = loop;
                    };
                    
                    vobTMode = cvobTMode_Select;
                };
            };
        };
        
        if (vobTMode == cvobTMode_Select_Confirm) {
            //Backup collision bitfields
            vobTCollBits = VobGetCollBits (vobTPtr);
            
            //Remove active collisions
            VobRemoveCollBits (vobTPtr, vobTCollBits);
            
            vobTMode = cvobTMode_Moving;
    
            Hero_UnLock ();
        };
        
        //Moving mode
        if (vobTMode == cvobTMode_Moving) {
            if (vobTPtr) {
                //Move object in front of hero (X, Y, Z)
                MoveVobInFront (hero, vobTPtr);
            
                Vob = _^ (vobTPtr);
            
                //Rotate
                TRF_RotateLocal (Vob, mkf (vobTRotX), mkf (vobTRotY), mkf (vobTRotZ));
                vobTRotX = 0; vobTRotY = 0; vobTRotZ = 0;
            
                //Align vob to floor
                if (vobTModeXYZE != cvobTRotationMode_E) {
                    if (vobTModeAlignToFloor == TRUE) {
                        SetVobToFloor (vobTPtr);
                    };
                 };
            };
        };
        
        //Stop transport mode
        if (vobTMode == cvobTMode_Done) {
            //Restore collision bitfields
            VobRestoreCollBits (vobTPtr, vobTCollBits);
            
            //Disable vobTMode
            vobTMode = cvobTMode_Disabled;
        };
    };
    This one will be triggered from gameKeyEvents.d
    Code:
    /*
     * Customizable function to handle key events (pressed is FALSE: key is held, pressed is TRUE: key press onset)
     */
    func void Game_KeyEvent(var int key, var int pressed) {
    
        //--- Activate Vob Transport mode
        
        if (key == KEY_LBRACKET) && (pressed)
        {
            //Start vob/focus selection
            if (vobTMode == cvobTMode_Disabled) {
                vobTMode = cvobTMode_Init;
                vobTMovementSpeed = 1;
            };
    
            //Confirm selection
            if (vobTMode == cvobTMode_Select) {
                vobTMode = cvobTMode_Select_Confirm;
            };
            
            //End interaction
            if (vobTMode == cvobTMode_Moving) {
                Vob_SetDrawBBox3D (vobTPtr, 0);
    
                Hero_UnLock ();
                
                vobTModeXYZE = cvobTRotationMode_0;
                vobTMode = cvobTMode_Done;
            };
        };
    
        if (vobTMode == cvobTMode_Select) {
            //Select previous Vob
            if (key == KEY_LEFTARROW) && (pressed) {
                if (vobTMode == cvobTMode_Select) {
                    vobTMode = cvobTMode_Select_Previous;
                };
            };
            
            //Select next Vob
            if (key == KEY_RIGHTARROW) && (pressed) {
                if (vobTMode == cvobTMode_Select) {
                    vobTMode = cvobTMode_Select_Next;
                };
            };
            
            //Cancel selection (escape is bringing main menu :()
            if (key == KEY_ESCAPE) && (pressed)
            || (key == KEY_RBRACKET) && (pressed) {
                Vob_SetDrawBBox3D (vobTPtr, 0);
                
                Hero_UnLock ();
    
                vobTModeXYZE = cvobTRotationMode_0;
                vobTMode = cvobTMode_Disabled;
            };
        };
        
        if (vobTMode == cvobTMode_Moving) {
            //Align to surface on/off
            if (vobTModeXYZE != cvobTRotationMode_E) {
                if (key == KEY_RBRACKET) && (pressed) {
                    vobTModeAlignToFloor = !vobTModeAlignToFloor;
                };
            };
    
            //Space - increase movement speed 1 - 10 - 20
            if (key == KEY_SPACE) && (pressed) {
                if (vobTMovementSpeed == 1) {
                    vobTMovementSpeed = 10;
                } else
                if (vobTMovementSpeed == 10) {
                    vobTMovementSpeed = 20;
                } else {
                    vobTMovementSpeed = 1;
                };        
            };
            
            //X - rotate X axis
            if (key == KEY_X) && (pressed) {
                if (vobTModeXYZE == cvobTRotationMode_X) {
                    vobTModeXYZE = cvobTRotationMode_0;
                    Hero_UnLock ();
                } else {
                    vobTModeXYZE = cvobTRotationMode_X;
                    Hero_Lock ();
                };
            };
    
            //Y - rotate Y axis
            if (key == KEY_Y) && (pressed) {
                if (vobTModeXYZE == cvobTRotationMode_Y) {
                    vobTModeXYZE = cvobTRotationMode_0;
                    Hero_UnLock ();
                } else {
                    vobTModeXYZE = cvobTRotationMode_Y;
                    Hero_Lock ();
                };
            };
    
            //Z - rotate Z axis
            if (key == KEY_Z) && (pressed)
            {
                if (vobTModeXYZE == cvobTRotationMode_Z) {
                    vobTModeXYZE = cvobTRotationMode_0;
                    Hero_UnLock ();
                } else {
                    vobTModeXYZE = cvobTRotationMode_Z;
                    Hero_Lock ();
                };
            };
            
            //E - elevate
            if (key == KEY_E) && (pressed)
            {
                if (vobTModeXYZE == cvobTRotationMode_E) {
                    vobTModeXYZE = cvobTRotationMode_0;
                    Hero_UnLock ();
                } else {
                    vobTModeXYZE = cvobTRotationMode_E;
                    Hero_Lock ();
                };
            };
    
            //--- Rotation - left / down key
            if (key == KEY_LEFTARROW) && (pressed)
            || (key == KEY_DOWNARROW) && (pressed) {
    
                if (vobTModeXYZE == cvobTRotationMode_X) {
                    vobTRotX -= vobTMovementSpeed;
                };
                if (vobTModeXYZE == cvobTRotationMode_Y) {
                    vobTRotY -= vobTMovementSpeed;
                };
                if (vobTModeXYZE == cvobTRotationMode_Z) {
                    vobTRotZ -= vobTMovementSpeed;
                };
            };
            // right / up key
            if (key == KEY_RIGHTARROW) && (pressed)
            || (key == KEY_UPARROW) && (pressed) {
                if (vobTModeXYZE == cvobTRotationMode_X) {
                    vobTRotX += vobTMovementSpeed;
                };
                if (vobTModeXYZE == cvobTRotationMode_Y) {
                    vobTRotY += vobTMovementSpeed;
                };
                if (vobTModeXYZE == cvobTRotationMode_Z) {
                    vobTRotZ += vobTMovementSpeed;
                };
            };
            
            //--- Elevation - up - down key
            if (key == KEY_UPARROW) && (pressed) {
                if (vobTModeXYZE == cvobTRotationMode_E) {
                    vobTElevation += vobTMovementSpeed;
                };
            };
    
            if (key == KEY_DOWNARROW) && (pressed) {
                if (vobTModeXYZE == cvobTRotationMode_E) {
                    vobTElevation -= vobTMovementSpeed;
                };
            };
            
            //--- Safety checks for rotation
            if (vobTRotX < 0) { vobTRotX = 360 - (0 - vobTRotX); };
            if (vobTRotY < 0) { vobTRotY = 360 - (0 - vobTRotY); };
            if (vobTRotZ < 0) { vobTRotZ = 360 - (0 - vobTRotZ); };
    
            if (vobTRotX > 360) { vobTRotX = vobTRotX - 360; };
            if (vobTRotY > 360) { vobTRotY = vobTRotY - 360; };
            if (vobTRotZ > 360) { vobTRotZ = vobTRotZ - 360; };
        };
    };
    Geändert von F a w k e s (25.12.2020 um 18:47 Uhr) Grund: Added AI_TurnToVob piece + check for vobTPtr = 0 .

  5. Beiträge anzeigen #85 Zitieren
    Serima Avatar von Fisk2033
    Registriert seit
    Dec 2010
    Ort
    Dresden
    Beiträge
    5.803
     
    Fisk2033 ist offline
    I want to use this system in Gothic 2... I paste your code into a new file and added the missing G2 constats (oCMobLadder_vtbl and cZVob_vtbl). After that I added "Game_KeyEventInit()" and "FF_ApplyOnce(FrameHandler_VobTransport)" to my init_global... But I can't activate the transport mode... Did I miss something?

  6. Beiträge anzeigen #86 Zitieren
    Serima Avatar von Fisk2033
    Registriert seit
    Dec 2010
    Ort
    Dresden
    Beiträge
    5.803
     
    Fisk2033 ist offline
    Ok it was my fault... works like a charm in g2!

  7. Beiträge anzeigen #87 Zitieren
    Local Hero
    Registriert seit
    Feb 2013
    Beiträge
    236
     
    pawbuj ist offline
    Fawkes, this is amazing!

    It would be nice to add some spell effect. will looks more in Gothic style.
    Geändert von pawbuj (18.03.2019 um 08:32 Uhr)

  8. Beiträge anzeigen #88 Zitieren
    Legende der Amazonen Avatar von Bisasam
    Registriert seit
    Dec 2006
    Ort
    Meine Faust in Sinis Gesicht
    Beiträge
    9.639
     
    Bisasam ist offline
    Say, since when do you work at this moving vob feature? I got it in my mod since about 2016 and it was one of my best features... until you released this script for everyone. I don't wanna say that I'm pissed. I'm just slightly... no theres no better word. I AM pissed. All the hard work and now everyone has it.


    "Das erinnert doch sehr erfreulich an das, was man sich als Gothicfan wünscht!"
    -Korallenkette

  9. Beiträge anzeigen #89 Zitieren
    Local Hero
    Registriert seit
    Feb 2017
    Beiträge
    270
     
    F a w k e s ist offline
    Zitat Zitat von Bisasam Beitrag anzeigen
    Say, since when do you work at this moving vob feature? I got it in my mod since about 2016 and it was one of my best features... until you released this script for everyone. I don't wanna say that I'm pissed. I'm just slightly... no theres no better word. I AM pissed. All the hard work and now everyone has it.
    Hi Bisasam,
    I started on 10th of March and finished what I wanted to have in it on 14th of March. I believe in open-source, that's why I shared my code, hoping it can be helpful to others.

  10. Beiträge anzeigen #90 Zitieren
    banned
    Registriert seit
    Jan 2009
    Ort
    Oberösterreich
    Beiträge
    2.393
     
    Moe ist offline
    Zitat Zitat von Bisasam Beitrag anzeigen
    Say, since when do you work at this moving vob feature? I got it in my mod since about 2016 and it was one of my best features... until you released this script for everyone. I don't wanna say that I'm pissed. I'm just slightly... no theres no better word. I AM pissed. All the hard work and now everyone has it.
    Ich kann ja verstehen, dass dich das ein bisschen ärgert, aber du kannst da F a w k e s nicht wirklich einen Vorwurf machen, meine ich. Er hat das Feature ja wohl völlig unabhängig von dir entwickelt. Ich weiß jetzt gar nicht, ob du das mal öffentlich außerhalb von deinen Tests präsentiert hast. Wie hätte F a w k es denn dieses Feature „stehlen“ sollen?
    Geändert von Moe (24.03.2019 um 13:59 Uhr)

  11. Beiträge anzeigen #91 Zitieren
    Dea
    Registriert seit
    Jul 2007
    Beiträge
    10.447
     
    Lehona ist offline
    Zitat Zitat von Bisasam Beitrag anzeigen
    Say, since when do you work at this moving vob feature? I got it in my mod since about 2016 and it was one of my best features... until you released this script for everyone. I don't wanna say that I'm pissed. I'm just slightly... no theres no better word. I AM pissed. All the hard work and now everyone has it.
    Modding is not a competition. It should be a way to express your ideas and create a wonderful and interesting experience for others. Feeling upset is okay, but expressing this anger openly (and feeling justified to do that!) just because someone decided to share his work with the community is despicable. How would you feel if Sektenspinner or Gottfried and me* never shared our work? Your feature relies on the spirit of open source as well, don't forget that.

    *Increasingly often I get the feeling I should simply license LeGo under the GPL to be done with this high school drama.

  12. Beiträge anzeigen #92 Zitieren
    Legende der Amazonen Avatar von Bisasam
    Registriert seit
    Dec 2006
    Ort
    Meine Faust in Sinis Gesicht
    Beiträge
    9.639
     
    Bisasam ist offline
    Das hier ist ein Forum, oder? Warum kann ich nicht schreiben, wie ich mich fühle und warum? Ich habe ihn nicht beleidigt. Es ist nur so, dass das (in meinen Augen) häufiger vorkommt. Letztens hat Mud-Freak ja meinen kompletten Taschendiebstahlscode neu geschrieben. Ich sage nicht, dass ich die Arbeit daran schlecht finde (zumal er ja auch noch gesagt hat, dass er lieber meinen Namen drunter stehen hätte weil er weiß, wie viel Arbeit da reingeflossen ist), es geht eher darum, dass mir oft das Gefühl gegeben wird, dass jeder alles besser kann als ich. Und das frustriert. Wieso werde ich denn gleich so angefahren, wenn ich das mal anspreche? Ich bin keine Heilige, ich habe Gefühle und die würde ich gern an- und aussprechen statt sie in mich reinzufressen.
    Im Moment komme ich mir so vor, als würde ich eine Wissenschaftliche Arbeit verfassen und jedes Mal, wenn ich etwas beinahe releasefertig habe, bringt jemand anderes es früher raus, wodurch ich wie der Abkupferer aussehe. Dabei soll das hier doch kein Wettbewerb sein. Warum fühlt es sich nur so an?

    Das Feature wurde übrigens schon in diesem Video öffentlich vorgestellt: https://www.youtube.com/watch?v=lve0nNTqFPs (letzte 5 Minuten) Soweit ich weiß gabs da auch ne News zu.


    "Das erinnert doch sehr erfreulich an das, was man sich als Gothicfan wünscht!"
    -Korallenkette
    Geändert von Bisasam (26.03.2019 um 21:24 Uhr)

  13. Homepage besuchen Beiträge anzeigen #93 Zitieren
    Apprentice Avatar von Migos
    Registriert seit
    Mar 2016
    Beiträge
    45
     
    Migos ist offline
    Hey Siemekk, thanks for the ani scripts!
    Zitat Zitat von Siemekk Beitrag anzeigen
    Because i finished work in Ikarus and now i'm using AST(Agama Script Tools) i decided to share my scripts
    Some Engine scripts:
    Code:
    func void SetAsPlayer (var C_NPC slf) 
    {
        const int oCNpc__SetAsPlayer = 7612064;
        CALL__thiscall (MEM_InstToPtr (slf), oCNpc__SetAsPlayer);
    };
    
    
    func int Menu_ReadInt(var string category, var string name) //int
    {
        var string value; value = Mem_GetGothOpt(category, name);
        return STR_ToInt(value);
    };
    
    
    
    
    func void Menu_WriteInt(var string category, var string name, var int value)
    {
        MEM_SetGothOpt(category,name, IntToString(value));
    };
    
    
    func int oCNpc_GetModel(var int npc) //zCModel*
    {
        const int oCNpc__GetModel = 7571232;
        CALL__thiscall(MEM_InstToPtr(npc), oCNpc__GetModel);
        return CALL_RetValAsInt();
    };
    
    
     
    func int AniIsActive(var c_npc slf, var string aniname) //BOOL
    {
        var int ptr; ptr = oCNpc_GetModel(slf);
        const int zCModel_AniIsActive     =     5727888;//0x00576690
    
    
        CALL_zStringPtrParam(Str_Upper(aniname));
        CALL__thiscall(ptr,zCModel_AniIsActive);
        return CALL_RetValAsInt();    
    };
     
    
    
    func int zCVisual_LoadVisual(var string vis) //zCVisual*
    {
        const int zCVisual__LoadVisual = 6318800; //0x00606AD0
        CALL_zStringPtrParam(STR_Upper(vis));
        CALL__cdecl(zCVisual__LoadVisual);
        
        return CALL_RetValAsInt();
    };
    
    
    func int StringIsEmpty(var string str)    //BOOL
    {
        if(STR_Len(str)>=1)
        {
            return true;
        };
        return false;
    };
    
    
    func void Set_ItemVisual(var int itm, var string vis)
    {
        const int oCItem__SetVisual    = 7411984; //0x00711910
        CALL_PtrParam(zCVisual_LoadVisual(vis));
        CALL__thiscall(MEM_InstToPtr(itm),oCItem__SetVisual);
    }; 
    
    
    func int zCModel_SearchNode(var int model, var string node) //zCModelNodeInst*
    {
        CALL_zStringPtrParam(Str_Upper(node));
        CALL__thiscall(model, zCModel__SearchNode);
        return CALL_RetValAsInt();
    };
    
    
    func void Ext_PutInSlot(var int pnpc, var string node, var string visual)
    {
        const int zCModel__SetNodeVisual = 5739168;
        
        var int model; model = oCNpc_GetModel(pnpc);
        var int vis; vis = zCVisual_LoadVisual(visual);
        var int nde; nde = zCModel_SearchNode(model,node);
        CALL_IntParam(1);    //3 param
        CALL_PtrParam(vis);    //2 param - vis
        CALL_PtrParam(nde); //1 param get node 
        CALL__thiscall(model, zCModel__SetNodeVisual);
    };
    
    
    func void Ext_PutInSlot2(var int pnpc, var string node, var int vob)   //Used to mounts system (hero, "NODE", her.focus_vob)
    {
        var int model; model = oCNpc_GetModel(pnpc);
        var int nde; nde = zCModel_SearchNode(model,node);
        CALL_PtrParam(1); //1 param get node 
        var int vb; vb = MEM_InstGetOffset(vob);
        CALL_PtrParam(MEM_ReadInt(vb+200));    //2 param - vis
        CALL_PtrParam(nde); //1 param get node 
        CALL__thiscall(model, zCModel__SetNodeVisual);
    };
    
    
    func int Get_AniIDFromAniName(var int slf,  var string aniName) //int
    {
        const int zCModel__AniIDFromAniName    =    6365296; //0x00612070
    
    
        var int model; model = oCNpc_GetModel(slf);
        CALL_zStringPtrParam(Str_Upper(aniName));
        CALL__thiscall(model,zCModel__AniIDFromAniName);
        return CALL_RetValAsInt();    
    };
    
    
    func int GetAniFromAniID(var c_npc slf, var string aniName) //zCModelAni*
    {
        const int zCModel__GetAniFromAniID    =    4665168; //0x00472F50
        
        var int model; model = oCNpc_GetModel(slf);
        var int ani; ani = Get_AniIDFromAniName(slf,aniName);
    
    
        CALL_PtrParam(ani);
        CALL__thiscall(model,zCModel__GetAniFromAniID);
        return CALL_RetValAsInt();
    };
    
    
    func void Set_AniFPS(var c_npc slf, var string aniName, var int FPS)
    {
        var int ptr;
        ptr = GetAniFromAniID(slf, aniName);
        MEM_WriteInt(ptr+176, mkf(FPS));
    };
    
    
    func int GetNodeBBox3D(var int slf, var string bone) //Get Node BBox - Hitboxes or Check collision
    {
        var int model; model = oCNpc_GetModel(slf);
        var int node; node = zCModel_SearchNode(model,bone);
        CALL_PtrParam(node);
        CALL_RetValIsStruct(24); //6*4
        CALL__thiscall(model,zCModel__GetBBox3DNodeWorld);
        return CALL_RetValAsPtr();
    };
    
    
    func oCItem Hlp_GetItem(var int inst) //oCItem*
    {
        var zCPar_Symbol symb; symb = _^(MEM_GetSymbolByIndex(inst));
        _^(symb.offset);
    };
    I changed your ani functions a bit and made some more.
    Your scripts:
    Code:
    /**
     *    get pointer to model object 
     *    @param npc        pointer to npc object  
     */
    func int oCNpc_GetModel(var int npc) //zCModel*
    {
        const int oCNpc__GetModel = 7571232;
        CALL__thiscall(MEM_InstToPtr(npc), oCNpc__GetModel);
        return CALL_RetValAsInt();
    };
    
    /**
     *    checks if ani with given name is currently active 
     *    @param slf        npc 
     *    @param aniname    name of ani 
     */
    func int zCModel_AniIsActive(var c_npc slf, var string aniname) //BOOL
    {
        var int ptr; ptr = oCNpc_GetModel(slf);
        const int zCModel_AniIsActive     =     5727888;//0x00576690
    
        CALL_zStringPtrParam(Str_Upper(aniname));
        CALL__thiscall(ptr,zCModel_AniIsActive);
        return CALL_RetValAsInt();    
    };
    
    /**
     *    get pointer to ani object with given name of ani 
     *    @param slf        npc 
     *    @param aniname    name of ani 
     */
    func int zCModel_AniFromAniName(var c_npc slf,  var string aniName) //zCModelAni*
    {
        const int zCModel__AniIDFromAniName    =    6365296; //0x00612070
        const int zCModel__GetAniFromAniID    =    4665168; //0x00472F50
    
        var int model; model = oCNpc_GetModel(slf);
        // get ani id 
        CALL_zStringPtrParam(Str_Upper(aniName));
        CALL__thiscall(model,zCModel__AniIDFromAniName);
        var int id; id = CALL_RetValAsInt();
        // get ani object ptr
        CALL_PtrParam(id);
        CALL__thiscall(model,zCModel__GetAniFromAniID);
        // return ptr to ani object 
        return CALL_RetValAsInt();    
    };
    And my new functions:
    Code:
    // Active ani functions
    
    /**
     *    get progress of given ani as float (0.0 to 1.0)
     *    given ani should be active (check first)
     *    @param slf        npc  
     *    @param aniName    name of the ani 
     */
    func int zCModel_GetProgressPercent(var c_npc slf, var string aniName) // float
    {
        var int ptr; ptr = oCNpc_GetModel(slf);
        const int zCModel__GetProgressPercent = 5763728; // 0x0057F290
        
        CALL_RetValIsFloat(); // method returns float 
        CALL_zStringPtrParam(Str_Upper(aniName));
        CALL__thiscall(ptr,zCModel__GetProgressPercent);
        return CALL_RetValAsFloat();
    };
    
    /**
     *    get pointer to active ani object 
     *    @param slf                npc 
     *    @param zCModelAniPtr    pointer to ani object 
     */
    func int zCModel_GetActiveAni(var c_npc slf, var int zCModelAniPtr) // zCModelAniActive*
    {
        var int ptr; ptr = oCNpc_GetModel(slf);
        const int zCModel__GetActiveAni = 5745568; // 0x0057ABA0
        
        CALL_PtrParam(zCModelAniPtr);
        CALL__thiscall(ptr,zCModel__GetActiveAni);
        return CALL_RetValAsInt();    
    };
    
    /**
     *    get the progress of current active ani as float (0.0 to 1.0)
     *    @param zCModelAniActivePtr     pointer to active ani object 
     */
    func int zCModelAniActive_GetProgressPercent(var int zCModelAniActivePtr) // float 
    {
        const int zCModelAniActive__GetProgressPercent = 5729376; // 0x00576C60
        
        CALL_RetValIsFloat(); // method returns float 
        CALL__thiscall(zCModelAniActivePtr,zCModelAniActive__GetProgressPercent);
        return CALL_RetValAsFloat();
    };
    
    // Model Ani 
    
    /**
     *    check if ani object is active 
     *    @param slf                npc 
     *    @param zCModelAniPtr    pointer to ani object 
     */
    func int zCModel_IsAniActive(var c_npc slf, var int zCModelAniPtr) //BOOL
    {
        var int ptr; ptr = oCNpc_GetModel(slf);
        const int zCModel__IsAniActive     =     4665232; //0x00472F90
    
        CALL_PtrParam(zCModelAniPtr);
        CALL__thiscall(ptr,zCModel__IsAniActive);
        return CALL_RetValAsInt();    
    };
    
    /**
     *    get pointer to ani with given id 
     *    @param slf        npc 
     *    @param id         id of ani 
     */
    func int zCModel_GetAniFromAniID(var c_npc slf, var int id) //zCModelAni*
    {
        const int zCModel__GetAniFromAniID    =    4665168; //0x00472F50
        
        var int model; model = oCNpc_GetModel(slf);
            
        CALL_IntParam(id);
        CALL__thiscall(model,zCModel__GetAniFromAniID);
        return CALL_RetValAsInt();
    };
    
    /**
     *    get name of ani 
     *    @param zCModelAniPtr    pointer to ani object 
     */
    func string zCModel_GetAniName(var int zCModelAniPtr) //zSTRING&
    {
        const int zCModelAni__GetAniName    =    5886304; //0x0059D160
        CALL__thiscall(zCModelAniPtr,zCModelAni__GetAniName);
        return CALL_RetValAszStringPtr(); 
    };
    
    /**
     *    recursive function to find the current active animation
     *    @param aniIdLoop    current point of search (should be 0 at start)
     *    @param endLoop        ending point of search 
     */
    func int GetAniID(var int aniIdLoop, var int endLoop) //zCModelAni*
    {
        if (aniIdLoop <= endLoop)
        {
            var int zCModelAniPtr; 
            zCModelAniPtr = zCModel_GetAniFromAniID(hero, aniIdLoop);
            // check if ani is active 
            if (zCModelAniPtr > 0 && zCModel_IsAniActive(hero, zCModelAniPtr))
            {
                return zCModelAniPtr; // found the ani!
            } else {
                return GetAniID(aniIdLoop + 1, endLoop); // recursive call 
            };
        } else {
            return -1; // failed to find current ani (shouldn't happen)
        };
    };
    zCModel_GetProgressPercent() and zCModelAniActive_GetProgressPercent() returning the same float value as int. Don't forget to cast the int values to floats with the scripts in float.d (castFromIntf(floatnumber) ).

    @Sektenspinner könntest du noch Zerxes Liste in dein Ikarus Paket mit aufnehmen? Wäre ganz praktisch, da ich erst das halbe Forum durchforsten musste, bis ich loslegen konnte.
    Link: https://forum.worldofplayers.de/foru...7#post17631567
    [Bild: spineSignature.php?name=Migos]
    Entwickler von Jharkendar-Online Deathmatch & Roleplay (zu finden in Spine).
    Komm doch auf unseren Discord und lerne unsere nette Community kennen.
    Mal gucken, was gerade entwickelt wird? Hier ist unsere Roadmap.
    Geändert von Migos (31.03.2019 um 18:03 Uhr)

  14. Beiträge anzeigen #94 Zitieren
    Ehrengarde Avatar von mud-freak
    Registriert seit
    Dec 2005
    Beiträge
    2.199
     
    mud-freak ist offline
    Zitat Zitat von Migos Beitrag anzeigen
    @Sektenspinner [...]
    Hey Mann, neu hier? [Bild: mud.png]

    Sektenspinner ist soweit ich weiß lange nicht mehr aktiv. Ich denke eine Verlinkung im Ikarus-Startpost könnte nicht schaden. Direkt in Ikarus mit aufnehmen halte ich aber nicht für sinnvoll.


    @Bisasam: Ich kann das nachvollziehen. Es ist ärgerlich, dass dieses Feature möglicherweise in deiner Mod nun nicht mehr so innovativ wirkt. Allerdings auch nur, wenn jemand eine Mod mit dem Feature vor deiner veröffentlicht. Selbst dann denke ich aber, dass deine Mod, die du von Beginn an (oder zumindest seit langem) um dieses Feature herum aufgebaut hast, viel mehr Tiefe bietet als das jede andere Mod könnte, die das Feature jetzt einfach noch irgendwie quer reinschlägt einfach nur "weil es ein cooles Feature" ist.
    Das Gefühl, dass "jeder alles besser kann", kannst du deshalb auch in größerem Kontext betrachten. Solange es funktioniert, ist dem Spieler völlig egal, wie ein Feature nun in einer Mod implementiert ist. Was aber nicht egal ist und wo es viel wichtiger ist "gut" drin zu sein, ist es wie man eine Geschichte erzählt und eben solche Features in Quests einbindet.

  15. Beiträge anzeigen #95 Zitieren
    Dea
    Registriert seit
    Jul 2007
    Beiträge
    10.447
     
    Lehona ist offline
    Grundsätzlich kann ich natürlich den Unmut oder die Frustration über die Geschehnisse verstehen, allerdings möchte ich eben verhindern, dass sich jemand aus diesen Gründen mit der Veröffentlichung von Scripten o.ä. zurückhält, z.B. um dir oder jemand anderem nicht auf die Füße zu treten. Denn das wäre wahrlich ein trauriger Verlust - unsere Community ist bereits jetzt klein genug und die meisten sind mit ihren eigenen Projekten beschäftigt, so dass nur wenige etwas beitragen, von dem wirklich alle Modder profitieren können. Ebenso glücklicher bin ich, dass der ScriptBin hier relativ gut angenommen wurde (und von mir in der nächsten Zeit auch mal aktualisiert wird - versprochen).

    Davon abgesehen würde ich gerne an mud-freaks Post verweisen, der das besser in Worte gefasst hat als ich es könnte. Technische Features mögen zwar eine Grundlage für Mods bieten, aber der eigentliche Erfolg - also eine gute Mod - kommt erst durch gutes Storywriting und eine immersive/interaktive Welt (und das weißt du doch eigentlich auch ).
    Dass es dir als (annähernde?) Allrounderin so vorkommt, als wären 'alle' besser als du ist nicht weiter verwunderlich - ich (und einige andere) haben sich die Freiheit genommen, nur das zu tun, was wir wirklich gut und gerne machen ((Feature-)Scripting in meinem Fall). Wenn ich mich mit dir im Spacern, 3D-Editing oder Story-/Questwriting vergleichen würde, bräuchte es keine 5 Minuten um jedem klarzumachen, dass ich den Kürzeren ziehen werde. Nach diesem Maßstab wärst du also sogar dreimal so gut wie ich


    Zitat Zitat von Migos Beitrag anzeigen
    @Sektenspinner könntest du noch Zerxes Liste in dein Ikarus Paket mit aufnehmen? Wäre ganz praktisch, da ich erst das halbe Forum durchforsten musste, bis ich loslegen konnte.
    Link: https://forum.worldofplayers.de/foru...7#post17631567
    Abgesehen von dem, was mud-freak sagt, findet man den Link dazu auch im LeGo-Wiki (unter Sonstiges -> EngineFunktionen). Hilft dir jetzt natürlich nicht mehr viel

  16. Homepage besuchen Beiträge anzeigen #96 Zitieren
    Apprentice Avatar von Migos
    Registriert seit
    Mar 2016
    Beiträge
    45
     
    Migos ist offline
    Zitat Zitat von mud-freak Beitrag anzeigen
    Hey Mann, neu hier? [Bild: mud.png]
    Hey, für WoG Verhältnisse wahrscheinlich schon Aber Gothic spiele ich schon weitaus länger
    Zitat Zitat von mud-freak Beitrag anzeigen
    Sektenspinner ist soweit ich weiß lange nicht mehr aktiv. Ich denke eine Verlinkung im Ikarus-Startpost könnte nicht schaden. Direkt in Ikarus mit aufnehmen halte ich aber nicht für sinnvoll.
    Ah schade, aber ja, so eine Verlinkung würde schon ausreichen. Mein Vorschlag war eher diese Funktionen schon als fertig aufrufbare Scripts zu implementieren und in das Ikarus Paket aufzunehmen. Wenn man dann noch nach und nach dokumentieren würde, was die Funktionen genau machen, würde das denke ich mal immens beim modden helfen.

    @Thora: Sehe das im SP Bereich halb so wild. Du hast ja nicht wirklich Konkurrenz hier, ganz im Gegensatz zu den MP Projekten, wo es schnell zum Problem wird wenn du nicht genügend Spieler auf dem Server hast
    Ich weiß noch, wie wir damals für CK nächtelang geforscht haben was alles GMP tauglich ist und was nicht. #Wetterwanze
    Letztendlich war die Lösung für den synchronen Regen einfach nur das Verstellen der Engine-Zeit auf 16:30 Uhr, weil es am ersten Tag genau um diese Uhrzeit immer regnet. Mittlerweile aber total nutzlos, weil es viel bessere Methoden gibt und der GMP auch weiter entwickelt wird. Was ich damit sagen will: man muss immer mit der Zeit gehen und auch erwarten, dass andere dasselbe machen. Also Kopf hoch und weitermachen.
    [Bild: spineSignature.php?name=Migos]
    Entwickler von Jharkendar-Online Deathmatch & Roleplay (zu finden in Spine).
    Komm doch auf unseren Discord und lerne unsere nette Community kennen.
    Mal gucken, was gerade entwickelt wird? Hier ist unsere Roadmap.

  17. Beiträge anzeigen #97 Zitieren
    Dea
    Registriert seit
    Jul 2007
    Beiträge
    10.447
     
    Lehona ist offline
    Zitat Zitat von Migos Beitrag anzeigen
    Hey, für WoG Verhältnisse wahrscheinlich schon Aber Gothic spiele ich schon weitaus länger

    Ah schade, aber ja, so eine Verlinkung würde schon ausreichen. Mein Vorschlag war eher diese Funktionen schon als fertig aufrufbare Scripts zu implementieren und in das Ikarus Paket aufzunehmen. Wenn man dann noch nach und nach dokumentieren würde, was die Funktionen genau machen, würde das denke ich mal immens beim modden helfen.
    Das sind mehrere tausend Funktionen, wenn ich mich nicht irre. Da der Daedalus-Compiler keine Optimierungen vornimmt, landen die dann immer auch in der Gothic.dat. Ich würde schätzen, dass das die Anzahl der Symbole um 5-10x erhöhen würde. Theoretisch ist das nicht schlimm (außer der Codestack hat eine maximale Größe?), aber praktisch sollte man das vermutlich lieber vermeiden.

  18. Beiträge anzeigen #98 Zitieren
    Local Hero
    Registriert seit
    Feb 2017
    Beiträge
    270
     
    F a w k e s ist offline

    G1 Disable damage animations and interruptions

    Hello folks,
    Fingers crossed that no one will be pissed off this time.

    I would like to share code, which will improve your Gothic 1 combat experience. So far I did not encounter any issues with it, I will appreciate every feedback if you see anything. If player is in fighting mode, this will disable 2 things - animations which are played when damage is inflicted and function oCNpc__Interrupt. In case that player was swarmed by NPCs (Molerats are great example) each attack would interrupt player's action. Which was incredibly annoying and frustrating.

    @Lehona - big thank you, I have used your code (original post below) as a starting point, and adapted it for G1:
    https://forum.worldofplayers.de/foru...1#post24744467

    Required:
    class definition for oSDamageDescriptor (from Lehona):
    https://forum.worldofplayers.de/foru...1#post19002341

    Code:
    /***
        Gothic 1
        Function will disable/enable oCNpc__Interrupt
    ***/
    FUNC VOID NPC_Interrupt_SetEnabled (var int enabled)
    {
        //00692830  .text     Debug data           ?Interrupt@oCNpc@@QAEXH@Z
        const int oCNpc__Interrupt = 6891568;
        
        MemoryProtectionOverride (oCNpc__Interrupt, 3);
        
        //RAM hex values @ h 00692830
        //83 EC 10 53 56 8B F1 8B 9E B4 09 00 00 ...
        
        if (enabled) {
            //Restore original values
            MEM_WriteByte (oCNpc__Interrupt, 131);            //83
            MEM_WriteByte (oCNpc__Interrupt + 1, 236);        //EC
            MEM_WriteByte (oCNpc__Interrupt + 2, 16);        //10
        } else {
            //Taken from LeGo 2.5.1 ReplaceEngineFuncI -> write return instruction at the beginning of a function
            MEM_WriteByte (oCNpc__Interrupt, 194);
            MEM_WriteByte (oCNpc__Interrupt + 1, 4);
            MEM_WriteByte (oCNpc__Interrupt + 2, 0);
        };
    };
    
    /***
        Gothic 1
        Hook below will disable animation & function oCNpc__Interrupt - both would interrupt player while fighting.
    ***/
    FUNC VOID _HOOK_DMG_ONDMG_ANIMATION ()
    {
        var C_NPC slf;
        slf = _^ (ECX);
        
        var oSDamageDescriptor dmgDescriptor;
        dmgDescriptor = _^ (MEM_ReadInt (ESP + 4));
        
        //Enable by default (seems like oCNpc__Interrupt is called right after oCNpc__OnDamage_Anim)
        NPC_Interrupt_SetEnabled (TRUE);
    
        //If damage was inflicted by Barrier (no attackerNpc) player was not thrown away
        if (!dmgDescriptor.attackerNpc) { return; };
        
        if (C_NPC_IsPlayer (slf))
        {
            //If player is not in fight mode, we can apply animations and interruption
            if (!NPC_IsInFightMode (slf, FMODE_FIST))
            && (!NPC_IsInFightMode (slf, FMODE_MELEE))
            && (!NPC_IsInFightMode (slf, FMODE_FAR))
            && (!NPC_IsInFightMode (slf, FMODE_MAGIC)) {
                return;
            };
            
            //We need to find out damageType
            var int damageType; damageType = 0;
    
            var C_NPC oth;
            oth = _^ (dmgDescriptor.attackerNpc);
            
            //Spell
            if (dmgDescriptor.spellID != 0)
            && (dmgDescriptor.spellID != -1) {
                //Seems like damageType = dmgDescriptor.spellLevel
                damageType = dmgDescriptor.spellLevel;
            };
           
            var C_Item weapon;
            
            //Weapon
            if (dmgDescriptor.itemWeapon != 0) {
                
                weapon = _^ (dmgDescriptor.itemWeapon);
                
                //Ranged weapon has spellID == -1
                //In case of ranged weapon dmgDescriptor.itemWeapon returns amunition
                //So we have to check either Readied weapon or Equipped weapon (fingers crossed NPC didn't switch these that fast)
                if (dmgDescriptor.spellID == -1) {
                    if (NPC_IsInFightMode(oth, FMODE_FAR)) {
                        weapon = NPC_GetReadiedWeapon (oth);
                    } else if (NPC_HasEquippedRangedWeapon (oth)) {
                        weapon = NPC_GetEquippedRangedWeapon (oth);
                    };
                };
            
                //Get weapon damageType
                damageType = weapon.damageType;
            //Fist mode - get NPC damageType
            } else {
                damageType = oth.damageType;
            };
            
            //If damage was inflicted by Troll (DAM_FLY) player was not thrown away - so don't do anything here
            if (damageType & DAM_FLY) { return; };
            
            if (damageType != 0) {
                //EAX = 0 will disable animation T_STUMBLE / T_STUMBLEB / T_GOTHIT / (maybe more animations ?)
                EAX = 0;
                
                //Disable interruption for player
                NPC_Interrupt_SetEnabled (FALSE);
            };
        };
    };
    Hook it with:
    Code:
        //I am sure this address is from Lehona as well :)
        HookEngine (7609592, 9, "_HOOK_DMG_ONDMG_ANIMATION");

  19. Beiträge anzeigen #99 Zitieren
    Local Hero
    Registriert seit
    Feb 2013
    Beiträge
    236
     
    pawbuj ist offline
    Many thanks for ur efforts. Looks like not many G1 bugs left.

    I heard about some problem with ice-wave spell (not tested!). Also haste potions needs to be fixed after save/load game.

  20. Beiträge anzeigen #100 Zitieren
    Local Hero
    Registriert seit
    Feb 2017
    Beiträge
    270
     
    F a w k e s ist offline

    G1 SPL_ICECUBE, SPL_ICEWAVE, SPL_FEAR fix

    Zitat Zitat von pawbuj Beitrag anzeigen
    Many thanks for ur efforts Fawkes. Looks like not many G1 bugs left.
    I heard about some problem with ice-wave spell. Also haste potions needs to be fixed after save/load game.
    Hi pawbuj,
    You can fix these spells: SPL_ICECUBE, SPL_ICEWAVE, SPL_FEAR (maybe more of them, I noticed these were trouble-makers) within hook for damage calculation. When these spells will hit NPC, their respective B_AssessMagic* functions will be called -> you can remove their B_AssessMagic* functions from func void B_AssessMagic ().

    If you don't have such hook, you can even use this one from my previous post _HOOK_DMG_ONDMG_ANIMATION:
    Code:
    FUNC VOID _HOOK_DMG_ONDMG_ANIMATION ()
    {
        var C_NPC slf;
        slf = _^ (ECX);
        
        var oSDamageDescriptor dmgDescriptor;
        dmgDescriptor = _^ (MEM_ReadInt (ESP + 4));
        
        //Enable by default (seems like oCNpc__Interrupt is called right after oCNpc__OnDamage_Anim)
        NPC_Interrupt_SetEnabled (TRUE);
    
        //If damage was inflicted by Barrier (no attackerNpc) player was not thrown away
        if (!dmgDescriptor.attackerNpc) { return; };
    
        var C_NPC oth;
        oth = _^ (dmgDescriptor.attackerNpc);
        
    //--- fix for spells SPL_ICECUBE, SPL_ICEWAVE, SPL_FEAR
        
        if (dmgDescriptor.spellID != 0)
        && (dmgDescriptor.spellID != -1) {
            
            var C_NPC self_backup;
            var C_NPC other_backup;
            
            //--- Backup self & other
            self_backup = Hlp_GetNPC (self);
            other_backup = Hlp_GetNPC (other);
            
            /***
            Call B_AssessMagic functions
            self = victim & other = attacker within B_AssessMagic
            ***/
            
            self = Hlp_GetNPC (slf);
            other = Hlp_GetNPC (oth);
            
            if (dmgDescriptor.spellID == SPL_ICECUBE)
            || (dmgDescriptor.spellID == SPL_ICEWAVE) {
                MEM_Call (B_AssessMagic_IceCube);
            };
    
            if (dmgDescriptor.spellID == SPL_FEAR) {
                MEM_Call (B_AssessMagic_Fear);
            };
    
            //Restore self & other
            self = Hlp_GetNPC (self_backup);
            other = Hlp_GetNPC (other_backup);
        };
    //---    
        if (C_NPC_IsPlayer (slf))
        {
            //If player is not in fight mode, we can apply animations and interruption
            if (!NPC_IsInFightMode (slf, FMODE_FIST))
            && (!NPC_IsInFightMode (slf, FMODE_MELEE))
            && (!NPC_IsInFightMode (slf, FMODE_FAR))
            && (!NPC_IsInFightMode (slf, FMODE_MAGIC)) {
                return;
            };
            
            //We need to find out damageType
            var int damageType; damageType = 0;
    
            //Spell
            if (dmgDescriptor.spellID != 0)
            && (dmgDescriptor.spellID != -1) {
                //Seems like damageType = dmgDescriptor.spellLevel
                damageType = dmgDescriptor.spellLevel;
            };
            
            var C_Item weapon;
            
            //Weapon
            if (dmgDescriptor.itemWeapon != 0) {
                
                weapon = _^ (dmgDescriptor.itemWeapon);
                
                //Ranged weapon has spellID == -1
                //In case of ranged weapon dmgDescriptor.itemWeapon returns amunition
                //So we have to check either Readied weapon or Equipped weapon (fingers crossed NPC didn't switch these that fast)
                if (dmgDescriptor.spellID == -1) {
                    if (NPC_IsInFightMode(oth, FMODE_FAR)) {
                        weapon = NPC_GetReadiedWeapon (oth);
                    } else if (NPC_HasEquippedRangedWeapon (oth)) {
                        weapon = NPC_GetEquippedRangedWeapon (oth);
                    };
                };
            
                //Get weapon damageType
                damageType = weapon.damageType;
            //Fist mode - get NPC damageType
            } else {
                damageType = oth.damageType;
            };
            
            //If damage was inflicted by Troll (DAM_FLY) player was not thrown away - so don't do anything here
            if (damageType & DAM_FLY) { return; };
            
            if (damageType != 0) {
                //EAX = 0 will disable animation T_STUMBLE / T_STUMBLEB / T_GOTHIT / (maybe more animations ?)
                EAX = 0;
                
                //Disable interruption for player
                NPC_Interrupt_SetEnabled (FALSE);
            };
        };
    };

Seite 5 von 10 « Erste 123456789 ... Letzte »

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