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 27 « Erste 1234567891216 ... Letzte »
Ergebnis 81 bis 100 von 538
  1. Beiträge anzeigen #81 Zitieren
    Knight Avatar von Draxes
    Registriert seit
    Aug 2007
    Ort
    Mainz
    Beiträge
    1.920
     
    Draxes ist offline
    Ich habe mal eine Frage zu der Lösung mit dem Schwierigkeitsgrad. Wie genau ist MENU_DIFFLEVEL in deinem Beispiel im Menü definiert und wie wird das gesetzt? Ich habe im Moment das Problem, dass ich nicht an den vor dem Spielstart ausgewählten (über ChoiceBox) Schwierigkeitsgrad herankomme und hoffe es mit der GetAnyParserSymbol-Methode lösen zu können.

  2. Beiträge anzeigen #82 Zitieren
    Ehrengarde Avatar von mud-freak
    Registriert seit
    Dec 2005
    Beiträge
    2.199
     
    mud-freak ist offline
    Zitat Zitat von Draxes Beitrag anzeigen
    Ich habe mal eine Frage zu der Lösung mit dem Schwierigkeitsgrad. Wie genau ist MENU_DIFFLEVEL in deinem Beispiel im Menü definiert und wie wird das gesetzt? Ich habe im Moment das Problem, dass ich nicht an den vor dem Spielstart ausgewählten (über ChoiceBox) Schwierigkeitsgrad herankomme und hoffe es mit der GetAnyParserSymbol-Methode lösen zu können.
    In dem Beispiel ist MENU_DIFFLEVEL einfach eine fest definierte Konstante zur simplen Demonstration. Wie GiftGrün seine Variable DifficultyLevel aus dem Menü heraus gesetzt hat, wäre tatsächlich interessant.

  3. Beiträge anzeigen #83 Zitieren
    Held Avatar von GiftGrün
    Registriert seit
    Jun 2011
    Ort
    Gewächshaus des Assassinen
    Beiträge
    5.010
     
    GiftGrün ist offline
    Ich habe einfach BadCodingPractices auf True gesetzt:

    In Menu_Defines.d Folgendes hinzugefügt:

    Code:
    var   int MENU_DIFFLEVEL;
    const int DIFF_UNKNOWN		= 0;
    const int DIFF_BONFIREHEALING	= 1 << 0;
    const int DIFF_ACHIEVEMENTS	= 1 << 1;
    const int DIFF_MARVIN		= 1 << 2;
    const int DIFF_TOUGHMONSTERS	= 1 << 3;
    const int DIFF_DEATHRESPAWN	= 1 << 4;
    const int DIFF_MONSTERRESPAWN	= 1 << 5;
    
    const int DIFF_EASY		= DIFF_BONFIREHEALING | DIFF_MARVIN | DIFF_MONSTERRESPAWN;
    const int DIFF_MEDIUM		= DIFF_ACHIEVEMENTS | DIFF_MONSTERRESPAWN;
    const int DIFF_HARD		= DIFF_ACHIEVEMENTS;
    const int DIFF_CHALLENGE	= DIFF_HARD | DIFF_TOUGHMONSTERS | DIFF_DEATHRESPAWN | DIFF_MONSTERRESPAWN;
    In Menu_Main.d folgendes geändert:

    Code:
    instance MENUITEM_MAIN_NEWGAME(C_MENU_ITEM_DEF) 
    {
    [...]
        // Aktionen
        onSelAction[0]	= SEL_ACTION_STARTMENU;
        onSelAction_S[0]= "MENU_DIFFICULTY";
    [...]
    };
    Und schließlich in der Menu_NewGame_Diff.d das Folgende verbrochen:

    Code:
    // *********************************************************************
    // Difficulty selection menu
    // *********************************************************************
    
    INSTANCE MENU_DIFFICULTY(C_MENU_DEF)
    {
        backpic     = MENU_BACK_PIC;
    
        items[0]    = "MENUITEM_DIFF_HEADING";
    
        items[1]    = "MENUITEM_DIFF_EASY";
        items[2]    = "MENUITEM_DIFF_MEDIUM";
        items[3]    = "MENUITEM_DIFF_HARD";
        items[4]    = "MENUITEM_DIFF_CHALLENGE";
        items[5]    = "MENUITEM_DIFF_BACK";
    
        flags       = flags | MENU_SHOW_INFO;
    };
    
    
    const int MENU_DIFF_DY         =  800;
    const int MENU_DIFF_START_Y    = 2600;
    
    INSTANCE MENUITEM_DIFF_HEADING(C_MENU_ITEM_DEF)
    {
        text[0]     =    "SCHWIERIGKEITSGRAD";
        type        =    MENU_ITEM_TEXT;
        // Position und Dimension
        posx        =    0;     posy        =    MENU_TITLE_Y;
        dimx        =    8192;
    
        flags       = flags & ~IT_SELECTABLE;
        flags       = flags | IT_TXT_CENTER;
    };
    
    INSTANCE MENUITEM_DIFF_EASY(C_MENU_ITEM_DEF)
    {
        backpic     = MENU_ITEM_BACK_PIC;
        text[0]     = "Einfach";
        text[1]     = DIFF_EASY_TEXT;  // Kommentar
    
        // Position und Dimension
        posx        = 0;        posy        = MENU_DIFF_START_Y + MENU_DIFF_DY*0;
        dimx        = 8192;     dimy        = 750;
    
        // Aktionen
        onSelAction[0]      = SEL_ACTION_STARTMENU;
        onSelAction_S[0]    = "MENU_DIFF_EASY_YESNO";
        // Weitere Eigenschaften
        flags = flags | IT_TXT_CENTER;
    };
    
    INSTANCE MENUITEM_DIFF_MEDIUM(C_MENU_ITEM_DEF)
    {
        backpic      = MENU_ITEM_BACK_PIC;
        text[0]      = "Normal";
        text[1]      = DIFF_MEDIUM_TEXT;  // Kommentar
    
        // Position und Dimension
        posx         = 0;       posy        = MENU_DIFF_START_Y + MENU_DIFF_DY*1;
        dimx         = 8192;    dimy        = 750;
    
        // Aktionen
        onSelAction[0]      = SEL_ACTION_STARTMENU;
        onSelAction_S[0]    = "MENU_DIFF_MEDIUM_YESNO";
        // Weitere Eigenschaften
        flags = flags | IT_TXT_CENTER;
    };
    
    INSTANCE MENUITEM_DIFF_HARD(C_MENU_ITEM_DEF)
    {
        backpic      = MENU_ITEM_BACK_PIC;
        text[0]      = "Schwer";
        text[1]      = DIFF_HARD_TEXT;  // Kommentar
    
        // Position und Dimension
        posx         = 0;       posy        = MENU_DIFF_START_Y + MENU_DIFF_DY*2;
        dimx         = 8192;    dimy        = 750;
    
        // Aktionen
        onSelAction[0]      = SEL_ACTION_STARTMENU;
        onSelAction_S[0]    = "MENU_DIFF_HARD_YESNO";
        // Weitere Eigenschaften
        flags = flags | IT_TXT_CENTER;
    };
    
    INSTANCE MENUITEM_DIFF_CHALLENGE(C_MENU_ITEM_DEF)
    {
        backpic      = MENU_ITEM_BACK_PIC;
        text[0]      = "Herausforderungsmodus";
        text[1]      = DIFF_CHALLENGE_TEXT;  // Kommentar
    
        // Position und Dimension
        posx         = 0;       posy        = MENU_DIFF_START_Y + MENU_DIFF_DY*3;
        dimx         = 8192;    dimy        = 750;
    
        // Aktionen
        onSelAction[0]      = SEL_ACTION_STARTMENU;
        onSelAction_S[0]    = "MENU_DIFF_CHALLENGE_YESNO";
        // Weitere Eigenschaften
        flags = flags | IT_TXT_CENTER;
    };
    
    /////////////////////////////////
    //        4. Eintrag leer            //
    /////////////////////////////////
    /*
    INSTANCE MENUITEM_DIFF_CUSTOM(C_MENU_ITEM_DEF)
    {
        backpic      = MENU_ITEM_BACK_PIC;
        text[0]      = "Benutzerdefiniert";
        text[1]      = "Schwierigkeitsgrad nach Belieben anpassen";  // Kommentar
    
        // Position und Dimension
        posx         = 0;       posy        = MENU_DIFF_START_Y + MENU_DIFF_DY*5;
        dimx         = 8192;    dimy        = 750;
    
        // Aktionen
        onSelAction[0]    = SEL_ACTION_STARTMENU;
        onSelAction_S[0]= "MENU_DIFF_CUSTOM";
        // Weitere Eigenschaften
        flags = flags | IT_TXT_CENTER;
    };
    */
    
    INSTANCE MENUITEM_DIFF_BACK(C_MENU_ITEM_DEF)
    {
        backpic      =    MENU_ITEM_BACK_PIC;
        text[0]      =    "Zurück";
        // Position und Dimension
        posx         = 1000;    posy        = MENU_BACK_Y+300;
        dimx         = 6192;    dimy        = MENU_OPT_DY;
        // Aktionen
        onSelAction[0]      = SEL_ACTION_BACK;
        // Weitere Eigenschaften
        flags = flags |IT_TXT_CENTER;
    };
    
    
    
    
    
    INSTANCE MENU_DIFF_EASY_YESNO(C_MENU_DEF)
    {
        backpic      = MENU_BACK_PIC;
    
        items[0]     = "MENUITEM_DIFF_EASY_HEADING";
    
        items[1]     = "MENUITEM_DIFF_EASY_YES";
        items[2]     = "MENUITEM_DIFF_NO";
    
        flags = flags | MENU_SHOW_INFO;
    };
    
    INSTANCE MENUITEM_DIFF_EASY_HEADING(C_MENU_ITEM_DEF)
    {
        text[0]      =    "EIN LEICHTES SPIEL STARTEN?";
        type         =    MENU_ITEM_TEXT;
        // Position und Dimension
        posx         = 0;       posy        = MENU_TITLE_Y;
        dimx         = 8192;
    
        flags = flags & ~IT_SELECTABLE;
        flags = flags | IT_TXT_CENTER;
    };
    
    INSTANCE MENUITEM_DIFF_EASY_YES(C_MENU_ITEM_DEF)
    {
        backpic      = MENU_ITEM_BACK_PIC;
        text[0]      = "Ja";
        text[1]      = DIFF_EASY_TEXT;  // Kommentar
    
        // Position und Dimension
        posx         = 0;       posy        = MENU_DIFF_START_Y + MENU_DIFF_DY;
        dimx         = 8192;    dimy        = 750;
    
        // Aktionen
        MENU_DIFFLEVEL      = DIFF_EASY;
        onSelAction[0]      = SEL_ACTION_CLOSE;
        onSelAction_S[0]    = "NEW_GAME";
        // Weitere Eigenschaften
        flags = flags | IT_TXT_CENTER;
    };
    
    
    
    INSTANCE MENU_DIFF_MEDIUM_YESNO(C_MENU_DEF)
    {
        backpic      = MENU_BACK_PIC;
    
        items[0]     = "MENUITEM_DIFF_MEDIUM_HEADING";
    
        items[1]     = "MENUITEM_DIFF_MEDIUM_YES";
        items[2]     = "MENUITEM_DIFF_NO";
    
        flags = flags | MENU_SHOW_INFO;
    };
    
    INSTANCE MENUITEM_DIFF_MEDIUM_HEADING(C_MENU_ITEM_DEF)
    {
        text[0]      =    "EIN NORMALES SPIEL STARTEN?";
        type         =    MENU_ITEM_TEXT;
        // Position und Dimension
        posx         = 0;       posy        = MENU_TITLE_Y;
        dimx         = 8192;
    
        flags = flags & ~IT_SELECTABLE;
        flags = flags | IT_TXT_CENTER;
    };
    
    INSTANCE MENUITEM_DIFF_MEDIUM_YES(C_MENU_ITEM_DEF)
    {
        backpic      = MENU_ITEM_BACK_PIC;
        text[0]      = "Ja";
        text[1]      = DIFF_MEDIUM_TEXT;  // Kommentar
    
        // Position und Dimension
        posx         = 0;       posy        = MENU_DIFF_START_Y + MENU_DIFF_DY;
        dimx         = 8192;    dimy        = 750;
    
        // Aktionen
        MENU_DIFFLEVEL      = DIFF_MEDIUM;
        onSelAction[0]      = SEL_ACTION_CLOSE;
        onSelAction_S[0]    = "NEW_GAME";
        // Weitere Eigenschaften
        flags = flags | IT_TXT_CENTER;
    };
    
    
    
    INSTANCE MENU_DIFF_HARD_YESNO(C_MENU_DEF)
    {
        backpic      = MENU_BACK_PIC;
    
        items[0]     = "MENUITEM_DIFF_HARD_HEADING";
    
        items[1]     = "MENUITEM_DIFF_HARD_YES";
        items[2]     = "MENUITEM_DIFF_NO";
    
        flags = flags | MENU_SHOW_INFO;
    };
    
    INSTANCE MENUITEM_DIFF_HARD_HEADING(C_MENU_ITEM_DEF)
    {
        text[0]      =    "EIN SCHWERES SPIEL STARTEN?";
        type         =    MENU_ITEM_TEXT;
        // Position und Dimension
        posx         = 0;       posy        = MENU_TITLE_Y;
        dimx         = 8192;
    
        flags = flags & ~IT_SELECTABLE;
        flags = flags | IT_TXT_CENTER;
    };
    
    INSTANCE MENUITEM_DIFF_HARD_YES(C_MENU_ITEM_DEF)
    {
        backpic      = MENU_ITEM_BACK_PIC;
        text[0]      = "Ja";
        text[1]      = DIFF_HARD_TEXT;  // Kommentar
    
        // Position und Dimension
        posx         = 0;       posy        = MENU_DIFF_START_Y + MENU_DIFF_DY;
        dimx         = 8192;    dimy        = 750;
    
        // Aktionen
        MENU_DIFFLEVEL      = DIFF_HARD;
        onSelAction[0]      = SEL_ACTION_CLOSE;
        onSelAction_S[0]    = "NEW_GAME";
        // Weitere Eigenschaften
        flags = flags | IT_TXT_CENTER;
    };
    
    
    
    INSTANCE MENU_DIFF_CHALLENGE_YESNO(C_MENU_DEF)
    {
        backpic      = MENU_BACK_PIC;
    
        items[0]     = "MENUITEM_DIFF_CHALLENGE_HEADING";
    
        items[1]     = "MENUITEM_DIFF_CHALLENGE_YES";
        items[2]     = "MENUITEM_DIFF_NO";
    
        flags = flags | MENU_SHOW_INFO;
    };
    
    INSTANCE MENUITEM_DIFF_CHALLENGE_HEADING(C_MENU_ITEM_DEF)
    {
        text[0]      =    "IM HERAUSFORDERUNGSMODUS STARTEN?";
        type         =    MENU_ITEM_TEXT;
        // Position und Dimension
        posx         = 0;       posy        = MENU_TITLE_Y;
        dimx         = 8192;
    
        flags = flags & ~IT_SELECTABLE;
        flags = flags | IT_TXT_CENTER;
    };
    
    INSTANCE MENUITEM_DIFF_CHALLENGE_YES(C_MENU_ITEM_DEF)
    {
        backpic      = MENU_ITEM_BACK_PIC;
        text[0]      = "Ja";
        text[1]      = DIFF_CHALLENGE_TEXT;
    
        // Position und Dimension
        posx         = 0;       posy        = MENU_DIFF_START_Y + MENU_DIFF_DY;
        dimx         = 8192;    dimy        = 750;
    
        // Aktionen
        MENU_DIFFLEVEL      = DIFF_CHALLENGE;
        onSelAction[0]      = SEL_ACTION_CLOSE;
        onSelAction_S[0]    = "NEW_GAME";
        // Weitere Eigenschaften
        flags = flags | IT_TXT_CENTER;
    };
    
    
    
    INSTANCE MENUITEM_DIFF_NO(C_MENU_ITEM_DEF)
    {
        backpic      =    MENU_ITEM_BACK_PIC;
        text[0]      =    "Nein";
        // Position und Dimension
        posx         = 1000;    posy        = MENU_DIFF_START_Y + MENU_DIFF_DY*2;
        dimx         = 6192;    dimy        = MENU_OPT_DY;
        // Aktionen
        onSelAction[0]    = SEL_ACTION_BACK;
        // Weitere Eigenschaften
        flags = flags |IT_TXT_CENTER;
    };
    Der Code in den INSTANCEs wird dann ausgeführt, sobald diese Instanz erstellt wird (d.h., sobald der Menüeintrag, z.B. "leicht", ausgewählt wird).
    “Da ist auch noch ein anderer Geruch in der Luft, der Geruch von Feuern, die in der Ferne brennen, mit einem Hauch Zimt darin - so riecht das Abenteuer!”
    ― aus Walter Moers' "Die 13 1/2 Leben des Käpt'n Blaubär"
    Geändert von GiftGrün (06.03.2018 um 20:55 Uhr)

  4. Beiträge anzeigen #84 Zitieren
    Knight Avatar von Draxes
    Registriert seit
    Aug 2007
    Ort
    Mainz
    Beiträge
    1.920
     
    Draxes ist offline
    @GiftGrün: Du bist gerade mein Held Ich werde mal schauen, ob ich's bei mir auch so ähnlich mache für den Spielstart. Danke für deine Antwort!

  5. Beiträge anzeigen #85 Zitieren
    Held Avatar von GiftGrün
    Registriert seit
    Jun 2011
    Ort
    Gewächshaus des Assassinen
    Beiträge
    5.010
     
    GiftGrün ist offline
    Im Spiel sieht das dann so aus: Video.
    “Da ist auch noch ein anderer Geruch in der Luft, der Geruch von Feuern, die in der Ferne brennen, mit einem Hauch Zimt darin - so riecht das Abenteuer!”
    ― aus Walter Moers' "Die 13 1/2 Leben des Käpt'n Blaubär"

  6. Beiträge anzeigen #86 Zitieren
    Knight Avatar von Draxes
    Registriert seit
    Aug 2007
    Ort
    Mainz
    Beiträge
    1.920
     
    Draxes ist offline
    Danke für das Video! Hat mir nochmal geholfen dein System zu verstehen. Ich hab's bei mir jetzt auch so einbauen können durch deine Beispiele und sogar mit meiner vorherigen Lösung das im Menü nachträglich noch umstellen zu können verbinden können. Falls der ungefähre Code jemanden interessiert:

    Code:
    // Zum einmaligen initialisieren des Schwierigkeitsgrades durch die Auswahl beim Spielstart
    func void UpdateDifficultyAfterLoading() {
        if (!modDifficultyInitialized) {
            var int symPtr; symPtr = GetAnyParserSymbol(MEM_ReadInt(menuParserPointerAddress), "MENU_DIFFLEVEL");
    
            if (symPtr) {
                    var zCPar_Symbol symb; symb = _^(symPtr);
                    setDifficulty(symb.content);
                    MEM_SetGothOpt("SPECIALOPTIONS", "difficulty", IntToString(symb.content)); 
            } else {
            	// Sollte eigentlich nicht passieren. Aber nur für den Fall.
                    setDifficulty(DIFFICULTY_03);
           	 	MEM_SetGothOpt("SPECIALOPTIONS", "difficulty", "2"); // Normal
            };
            modDifficultyInitialized = true;
        };
    };
    
    // Wird in Init_Global aufgerufen, um den Menüeintrag auf die Schwierigkeit des aktuellen Savegames zu stellen
    func void UpdateDifficultyInMenuForCurrentGame() {
    	MEM_SetGothOpt("SPECIALOPTIONS", "difficulty", IntToString(modDifficulty - 1));
    };
    
    // Wird in einer Triggerschleife regelmäßig aufgerufen, um regelmäßig zu prüfen, ob der Spieler den Schwierigkeitsgrad im Menü geändert hat
    func void UpdateDifficultyFromMenuOptions() {
    	if (modDifficulty) { // Weil wegen wird beim Spielstart gesetzt. Sollte unter keinen Umständen direkt am Anfang gefeuert werden.
    		var int difficulty;
    	        difficulty = STR_ToInt(MEM_GetGothOpt("SPECIALOPTIONS", "difficulty")) + 1; // Da Einstellungen 0-basiert
    	        setDifficulty(difficulty);
    	};
    };

  7. Beiträge anzeigen #87 Zitieren
    Ehrengarde Avatar von mud-freak
    Registriert seit
    Dec 2005
    Beiträge
    2.199
     
    mud-freak ist offline
    Zitat Zitat von Draxes Beitrag anzeigen
    Danke für das Video! Hat mir nochmal geholfen dein System zu verstehen. Ich hab's bei mir jetzt auch so einbauen können durch deine Beispiele und sogar mit meiner vorherigen Lösung das im Menü nachträglich noch umstellen zu können verbinden können. Falls der ungefähre Code jemanden interessiert:

    Code:
    // Zum einmaligen initialisieren des Schwierigkeitsgrades durch die Auswahl beim Spielstart
    func void UpdateDifficultyAfterLoading() {
        if (!modDifficultyInitialized) {
            var int symPtr; symPtr = GetAnyParserSymbol(MEM_ReadInt(menuParserPointerAddress), "MENU_DIFFLEVEL");
    
            if (symPtr) {
                    var zCPar_Symbol symb; symb = _^(symPtr);
                    setDifficulty(symb.content);
                    MEM_SetGothOpt("SPECIALOPTIONS", "difficulty", IntToString(symb.content)); 
            } else {
            	// Sollte eigentlich nicht passieren. Aber nur für den Fall.
                    setDifficulty(DIFFICULTY_03);
           	 	MEM_SetGothOpt("SPECIALOPTIONS", "difficulty", "2"); // Normal
            };
            modDifficultyInitialized = true;
        };
    };
    
    // Wird in Init_Global aufgerufen, um den Menüeintrag auf die Schwierigkeit des aktuellen Savegames zu stellen
    func void UpdateDifficultyInMenuForCurrentGame() {
    	MEM_SetGothOpt("SPECIALOPTIONS", "difficulty", IntToString(modDifficulty - 1));
    };
    
    // Wird in einer Triggerschleife regelmäßig aufgerufen, um regelmäßig zu prüfen, ob der Spieler den Schwierigkeitsgrad im Menü geändert hat
    func void UpdateDifficultyFromMenuOptions() {
    	if (modDifficulty) { // Weil wegen wird beim Spielstart gesetzt. Sollte unter keinen Umständen direkt am Anfang gefeuert werden.
    		var int difficulty;
    	        difficulty = STR_ToInt(MEM_GetGothOpt("SPECIALOPTIONS", "difficulty")) + 1; // Da Einstellungen 0-basiert
    	        setDifficulty(difficulty);
    	};
    };
    Das verstehe ich nicht ganz. Den Ansatz, die Symbole aus den Menu-Skripten auslesen zu können, bedarf es nur, wenn man wie GiftGrün vermeiden möchte, Einträge in der Gothic.ini zu erstellen. Da du diese nun aber explizit erstellst und darauf zurückgreifst, brauchst du diesen ganzen Umweg gar nicht, sondern kannst es direkt so machen, wie Dada das hier noch einmal gezeigt hat:


    Zitat Zitat von Dada Beitrag anzeigen
    Ich habe das (vielleicht) etwas einfacher gelöst.
    In den Menü-Skripten habe ich einen weiteren Einstellungspunkt angelegt, worüber man die Schwierigkeit einstellen kann.

    In einer FrameFunction lasse ich nun jeden Frame die gesetzte Einstellung überprüfen. Der Schwierigkeitsgrad wird ja in die Ini-Datei geschrieben und kann daher fix ausgelesen werden:

    Code:
    func void setDifficulty()
    {
        var int difficulty;
        difficulty = STR_ToInt(MEM_GetGothOpt("MAHLENDUR", "difficulty"));
    
        // Do Stuff...
    };
    Durch den ersten Start mit den geänderten Menü-Skripten, werden die Grundwerte automatisch eingetragen und daher ist auch keine Fehlerbehandlung ob "0" nötig.

  8. Beiträge anzeigen #88 Zitieren
    Knight Avatar von Draxes
    Registriert seit
    Aug 2007
    Ort
    Mainz
    Beiträge
    1.920
     
    Draxes ist offline
    @mud-freak

    Ich hatte das Problem, dass diese Lösung beim Spielstart nicht ganz geklappt hat. Dazu wollte ich den Schwierigkeitsgrad "normal" vorselektiert haben. Das hat beim ersten Spielstart auch nicht ganz hingehauen. Von daher finde ich das mit den zu Anfang auswählbaren Menüpunkten ganz charamant, da man dort einstellen kann, dass ein Menüpunkt vorselektiert ist.

  9. Beiträge anzeigen #89 Zitieren
    Held Avatar von GiftGrün
    Registriert seit
    Jun 2011
    Ort
    Gewächshaus des Assassinen
    Beiträge
    5.010
     
    GiftGrün ist offline
    Kennt ihr eigentlich das Problem, dass die Maussteuerung in Gothic auf high-DPI-Monitoren sehr langsam ist? Oder auf high-res-Monitoren. Das Problem ist, bei einem 4k-Monitor ist die Verlangsamung so stark, dass sogar MouseSensitivity=1 das Problem nicht mehr beheben kann. Und höhere Werte werden anscheinend ignoriert. Könnte man da vielleicht irgendwie einen Korrekturfaktor einbauen, oder die Funktion, die auf MouseSensitivity zugreift, so abändern, dass sie beliebige (positive) Werte zulässt?

    Falls das nicht möglich ist: Ist dieses Problem eigentlich verwandt damit, dass Gothic die Maus in der Mitte des Bildschirms "festklebt"? Das ist nämlich der Hauptgrund, wieso ich nicht einfach Windows die high-DPI-Skalierung übernehmen lasse (was dieses Problem möglicherweise lösen würde): Alles läuft prächtig, bis man ins Spiel kommt und der Held sich bei jeder noch so kleinen Mausbewegung schlagartig nach unten rechts dreht, weil die Maus in der Mitte des unskalierten Bildschirms sitzt, während für das kleinere Gothic-Fenster die Maus ganz am unteren rechten Rand zu liegen scheint. Das Resultat ist, dass Gothic jeden Maus-Input als "scharf nach unten rechts drehen" interpretiert.

    EDIT: Der Fehler tritt auch mit dem Systempack auf, deshalb meine Frage.
    “Da ist auch noch ein anderer Geruch in der Luft, der Geruch von Feuern, die in der Ferne brennen, mit einem Hauch Zimt darin - so riecht das Abenteuer!”
    ― aus Walter Moers' "Die 13 1/2 Leben des Käpt'n Blaubär"
    Geändert von GiftGrün (10.03.2018 um 07:04 Uhr)

  10. Beiträge anzeigen #90 Zitieren
    Local Hero
    Registriert seit
    Feb 2013
    Beiträge
    236
     
    pawbuj ist offline

    skipped npc dialogs

    I have problem with a Lego package Gothic 1.

    While playing a game at least few minutes some dialogs of npc have been skipped so very often I see sentences mostly pc _hero. there is no rule of that. Mostly after save/load game problem is partly fixed and occurs again in further time of the game. There is no rule, sometimes is very often OK.

    i wish to found a function which may be responsible for that, but I have no idea how to find it.

    I have that on all Lego versions.
    Geändert von pawbuj (16.03.2018 um 10:52 Uhr)

  11. Beiträge anzeigen #91 Zitieren
    Serima Avatar von Fisk2033
    Registriert seit
    Dec 2010
    Ort
    Dresden
    Beiträge
    5.802
     
    Fisk2033 ist offline
    Zitat Zitat von GiftGrün Beitrag anzeigen
    Kennt ihr eigentlich das Problem, dass die Maussteuerung in Gothic auf high-DPI-Monitoren sehr langsam ist? Oder auf high-res-Monitoren. Das Problem ist, bei einem 4k-Monitor ist die Verlangsamung so stark, dass sogar MouseSensitivity=1 das Problem nicht mehr beheben kann. Und höhere Werte werden anscheinend ignoriert. Könnte man da vielleicht irgendwie einen Korrekturfaktor einbauen, oder die Funktion, die auf MouseSensitivity zugreift, so abändern, dass sie beliebige (positive) Werte zulässt?

    Falls das nicht möglich ist: Ist dieses Problem eigentlich verwandt damit, dass Gothic die Maus in der Mitte des Bildschirms "festklebt"? Das ist nämlich der Hauptgrund, wieso ich nicht einfach Windows die high-DPI-Skalierung übernehmen lasse (was dieses Problem möglicherweise lösen würde): Alles läuft prächtig, bis man ins Spiel kommt und der Held sich bei jeder noch so kleinen Mausbewegung schlagartig nach unten rechts dreht, weil die Maus in der Mitte des unskalierten Bildschirms sitzt, während für das kleinere Gothic-Fenster die Maus ganz am unteren rechten Rand zu liegen scheint. Das Resultat ist, dass Gothic jeden Maus-Input als "scharf nach unten rechts drehen" interpretiert.

    EDIT: Der Fehler tritt auch mit dem Systempack auf, deshalb meine Frage.
    Probier mal:
    Zitat Zitat von Fisk2033 Beitrag anzeigen
    Ich weiß nicht, ob man es ohne das Systempack von MarGoth so nutzen kann, aber ich habe es hin bekommen!

    In der ini hab ich den Eintrag:
    zMouseRotationScale=4.0

    gemacht und schon kann ich mich ohne Probleme mit der Maus bewegen! :P

  12. Beiträge anzeigen #92 Zitieren
    Held Avatar von GiftGrün
    Registriert seit
    Jun 2011
    Ort
    Gewächshaus des Assassinen
    Beiträge
    5.010
     
    GiftGrün ist offline
    Zitat Zitat von Fisk2033 Beitrag anzeigen
    Probier mal:
    Vielen Dank, es bessert das Problem etwas (es scheint aber auf horizontale Bewegung mehr zu wirken als auf vertikale ).
    “Da ist auch noch ein anderer Geruch in der Luft, der Geruch von Feuern, die in der Ferne brennen, mit einem Hauch Zimt darin - so riecht das Abenteuer!”
    ― aus Walter Moers' "Die 13 1/2 Leben des Käpt'n Blaubär"

  13. Beiträge anzeigen #93 Zitieren
    now also in your universe  Avatar von Milky-Way
    Registriert seit
    Jun 2007
    Beiträge
    15.205
     
    Milky-Way ist gerade online
    Zitat Zitat von pawbuj Beitrag anzeigen
    I have problem with a Lego package Gothic 1.

    While playing a game at least few minutes some dialogs of npc have been skipped so very often I see sentences mostly pc _hero. there is no rule of that. Mostly after save/load game problem is partly fixed and occurs again in further time of the game. There is no rule, sometimes is very often OK.

    i wish to found a function which may be responsible for that, but I have no idea how to find it.

    I have that on all Lego versions.
    Two simple reasons come to mind:

    1) have you updated the output units?

    2) dialogues that end with AI_StopProcessInfos(self); cause problems if self doesn't say anything beforehand (i.e. only other speaks).

  14. Beiträge anzeigen #94 Zitieren
    Adventurer
    Registriert seit
    Sep 2013
    Beiträge
    66
     
    Vic7im ist offline
    Morning everyone. Is there a way to add debuffs to enemies using LeGo buff functionality?

    I'm having a crash every time the buff is called, here's the code for the debuff itself
    Spoiler:(zum lesen bitte Text markieren)
    Code:
    instance Bleed(lCBuff) {
            name = "Bleeding";
            bufftype = BUFF_BAD;
            
            durationMS = 10*1000; 
            tickMS = 1000; 
            onTick = SAVE_GetFuncID(Bleed_damage);
            buffTex = "POISON.TGA"; //Needs Change!
    };
    func void Bleed_damage(var int bh) {
        var int ptr; ptr = Buff_GetNpc(bh);
        if (!ptr) { return; }; 
    
    
        var c_npc n; n = _^(ptr);
        Wld_PlayEffect("BleedEffect",n,n,0,0,0,FALSE);    
        B_MagicHurtNpc(hero,n,hero.level);
    };


    the debuff is called with a 50% chance on a critical hit, I've put this code in the Dmg_OnDmg function Lehona did a while back:

    Spoiler:(zum lesen bitte Text markieren)
    Code:
                        if(Hlp_Random(101)<=50)
                        {
                            Buff_ApplyUnique(oth,Bleed);
                        };

    I'm not putting the rest of it because I already know it works perfectly. The logic is that the debuff is applied before calculating the damage, then the damage is calculated (return dmg; ).

    Here's the ZSpy log at 10.
    Spoiler:(zum lesen bitte Text markieren)
    Code:
    [i] 07:16 Info: 10 C:     SND: PlaySound3D: WHOOSH for vob: PC_HERO .... <zSndMss.cpp,#1508>
    [i] 07:16 Info:  8 U:     EM: oCNpc:SH ---[oCMsgAttack:EV_ATTACKLEFT(Job)]---> oCNpc:SH .... <zEventMan.cpp,#199>
    [i] 07:16 Info:  8 U:     EM: oCNpc:SH ---[oCMsgAttack:EV_ATTACKFORWARD(Job)]---> oCNpc:SH .... <zEventMan.cpp,#199>
    [f] 07:16 Fault: 0 Q:     [start of stacktrace]
    [f] 07:16 Fault: 0 Q:             MEMINT_HANDLEERROR(3, 'MEM_PtrToInst: Invalid pointer: -1')    +   62 bytes
    [f] 07:16 Fault: 0 Q:             MEM_ERROR('MEM_PtrToInst: Invalid pointer: -1')                +   21 bytes
    [f] 07:16 Fault: 0 Q:             MEM_PTRTOINST(457846256)                                       +  101 bytes
    [f] 07:16 Fault: 0 Q:             BLEED_DAMAGE(104)                                              +   44 bytes
    [f] 07:16 Fault: 0 Q:             MEM_CALLBYID(21663)                                            +  224 bytes
    [f] 07:16 Fault: 0 Q:             _BUFF_DISPATCHER(104)                                          +  142 bytes
    [f] 07:16 Fault: 0 Q:             FRAMEFUNCTIONS(105)                                            +  104 bytes
    [f] 07:16 Fault: 0 Q:             FOREACHHNDL(8981, FRAMEFUNCTIONS)                              +  263 bytes
    [f] 07:16 Fault: 0 Q:             [UNKNOWN]                                                      +597504093 bytes
    [f] 07:16 Fault: 0 Q:             _FF_HOOK()                                                     +   32 bytes
    [f] 07:16 Fault: 0 Q:             MEM_CALLBYID(21663)                                            +  224 bytes
    [f] 07:16 Fault: 0 Q:             _HOOK(693344520, 401510832, 0, 20315296, 20315164, 0, 8635020, 401510832, 466091680) +  498 bytes
    [f] 07:16 Fault: 0 Q:             [UNKNOWN]                                                      +610853323 bytes
    [f] 07:16 Fault: 0 Q:     [end of stacktrace]
    [f] 07:16 Fault: 0 Q:     MEM_PtrToInst: Invalid pointer: -1
    [w] 07:16 Warn:  0 C:     Wld_PlayEffect: Origin Script Instance is NULL! .... <oGameExternal.cpp,#1711>
    [w] 07:16 Warn:  0 C:     SCRIPT: Npc_ChangeAttribute(): illegal param: "B_MAGICHURTNPC.OTH" is NULL. .... <oGameExternal.cpp,#252>
    [w] 07:16 Warn:  0 C:     SCRIPT: last parser func-name: _HOOK .... <oGameExternal.cpp,#262>
    [w] 07:16 Warn:  0 C:     SCRIPT: Npc_IsDead(): illegal param: "B_MAGICHURTNPC.OTH" is NULL. .... <oGameExternal.cpp,#252>
    [w] 07:16 Warn:  0 C:     SCRIPT: last parser func-name: _HOOK .... <oGameExternal.cpp,#262>


    Without ZSpy the game crashes, with ZSpy it says this ^, the NPC doesn't lose hp and the hero somehow gets the XP. I'm clueless, is there a way to fix this or an alternative? Thank you!

    Edit: Upon trying again, it gave me XP worth of a sheep, a wolf and a couple 200 XP. I don't know why hahaha, I was focusing the enemy the whole time (who didn't break a sweat, didn't lose any hp)
    Geändert von Vic7im (17.03.2018 um 11:38 Uhr)

  15. Beiträge anzeigen #95 Zitieren
    Dea
    Registriert seit
    Jul 2007
    Beiträge
    10.446
     
    Lehona ist offline
    This is a weird error. MEM_PtrToInst is called with a seemingly legal pointer (457846256), yet the MEM_Error-Line shows a pointer of -1. Looking at the code of MEM_PtrToInst there is no reason to have different values on those two lines of the stacktrace, the parameter is taken directly and turned into a string.

    Code:
    func MEMINT_HelperClass MEM_PtrToInst (var int ptr) {
        var MEMINT_HelperClass hlp;
        const int hlpOffsetPtr = 0;
        if (!hlpOffsetPtr) {
            hlpOffsetPtr = MEM_ReadIntArray (currSymbolTableAddress, hlp) + zCParSymbol_offset_offset;
        };
        
        if (ptr <= 0) {
            if (ptr < 0) {
                MEM_Error (ConcatStrings ("MEM_PtrToInst: Invalid pointer: ", IntToString (ptr)));
                return;
            } else if (!MEM_AssignInstSuppressNullWarning) {
                /* Instanzen die Null sind, will man eigentlich nicht, die machen nur Ärger. */
                MEM_Warn ("MEM_PtrToInst: ptr is NULL. Use MEM_NullToInst if that's what you want.");
            };
            
            MEM_WriteInt(hlpOffsetPtr, 0);
        } else {
            MEM_WriteInt(hlpOffsetPtr, ptr);
        };
        MEMINT_StackPushInst (hlp);
    };

    Are you initializing the buffs using LeGo_Init(LeGo_All | LeGo_Buffs)? They have to be initialized explicitly because they have not been tested sufficiently. Unfortunately that should only impact the buff display of the hero, but maybe there's some other bug, so you should try that first.

    Does that happen every time you try it? Are there any level changes involved? If I can reproduce the bug I can probably fix it.


    Edit: Ikarus does some funky stuff to _^() to increase performance, that may be the reason why it displays 457846256 instead of -1 (probably the pointer to -1). That happens because Buff_GetNpc() returns -1 when the NPC was not found (e.g. level change). This should be considered a bug because missing pointers are generally signalled by a 0. For now you can change line 69 in Talents.d to a 0, this change will be included in later releases automatically.

    This should properly guard your function so it will just exit instead of accessing empty instances/invalid pointers. So at least it won't crash anymore...

    Edit2: Are you using the new version of the damage script that includes the damage descriptor? I can't see a reason for this behaviour, but it's new and might have bugs?
    Geändert von Lehona (17.03.2018 um 13:23 Uhr)

  16. Beiträge anzeigen #96 Zitieren
    Adventurer
    Registriert seit
    Sep 2013
    Beiträge
    66
     
    Vic7im ist offline
    Zitat Zitat von Lehona Beitrag anzeigen
    Edit: Ikarus does some funky stuff to _^() to increase performance, that may be the reason why it displays 457846256 instead of -1 (probably the pointer to -1). That happens because Buff_GetNpc() returns -1 when the NPC was not found (e.g. level change). This should be considered a bug because missing pointers are generally signalled by a 0. For now you can change line 69 in Talents.d to a 0, this change will be included in later releases automatically.

    This should properly guard your function so it will just exit instead of accessing empty instances/invalid pointers. So at least it won't crash anymore...

    Edit2: Are you using the new version of the damage script that includes the damage descriptor? I can't see a reason for this behaviour, but it's new and might have bugs?

    Thank you for your answer, I'll edit the line right away. Yes, I've started LeGo using | LeGo_Buffs in Startup.d.

    To be frank I thought there was only ONE version of the damage script, I'll find the new one and edit this message when I'll try it.

    In the meantime, I've found a workaround to "force" the game to recognize the hero's focus as THE target (since it happens when swining the sword at someone, there's 99.9% chance of success) and it works now. Here's what I changed:
    Spoiler:(zum lesen bitte Text markieren)
    Code:
    func void Bleed_damage(var int bh) {
        var int ptr; ptr = Buff_GetNpc(bh);
        if (!ptr) { return; };
        var oCNpc _hero; _hero = Hlp_GetNpc(hero);
        var c_npc pNpc; pNpc = MEM_PtrToInst(_hero.focus_vob);    
        var c_npc n; n = _^(ptr);
        
        if(!Hlp_Is_oCNpc(_hero.focus_vob))
        {
        return;
        }    
        else 
        {
        Wld_PlayEffect("BleedEffect",pNpc,pNpc,0,0,0,FALSE);    
        B_MagicHurtNpc(hero,pNpc,hero.level);
        };
    };


    I know, it's so spaghetti and wrong that it hurts, but it works

    Edit #2: Without "workaround", doesn't work with the new dmg_ondmg function.
    Levelchange, with the workaround, is NOT an issue. Script works fine after save/load and levelchange.
    Geändert von Vic7im (19.03.2018 um 17:23 Uhr) Grund: Pasted wrong workaround, fixed with highlighted changes.

  17. Beiträge anzeigen #97 Zitieren
    Local Hero
    Registriert seit
    Feb 2017
    Beiträge
    270
     
    F a w k e s ist offline
    Zitat Zitat von pawbuj Beitrag anzeigen
    I have problem with a Lego package Gothic 1.

    While playing a game at least few minutes some dialogs of npc have been skipped so very often I see sentences mostly pc _hero. there is no rule of that. Mostly after save/load game problem is partly fixed and occurs again in further time of the game. There is no rule, sometimes is very often OK.

    i wish to found a function which may be responsible for that, but I have no idea how to find it.

    I have that on all Lego versions.
    Hey pawbuj,
    I had same problem! It took me a while till I fixed it - I have noticed in zSpy log following message:

    NPC: Output-Unit: ... not started. Another NSC is having conversation with targetNPC: PC_HERO

    [Bild: gm_fix_dialog.png]

    From that I assumed that hero got somehow into another conversation with another NPC's. As soon as I have updated these 2 functions below - problem was fixed (red is old code, green adjusted):
    Code:
    FUNC VOID B_Say (var C_NPC slf, var C_NPC oth, var string text)
    {
    B_SmartTurnToNpc (slf, oth);
    //AI_OutputSVM (slf, oth, text);
    if (NPC_IsInState (slf, ZS_Talk)) || (NPC_IsInState (oth, ZS_Talk)) {
    AI_OutputSVM (slf, oth, text);
    } else {
    AI_OutputSVM (slf, NULL, text);
    };
    }; FUNC VOID B_SayOverlay (var C_NPC slf, var C_NPC oth, var string text) {
    B_SmartTurnToNpc (slf, oth);
    //AI_OutputSVM_Overlay (slf, oth, text);
    if (NPC_IsInState (slf, ZS_Talk)) || (NPC_IsInState (oth, ZS_Talk)) {
    AI_OutputSVM_Overlay (slf, oth, text);
    } else {
    AI_OutputSVM_Overlay (slf, NULL, text);
    };
    };
    Geändert von F a w k e s (08.02.2019 um 19:27 Uhr)

  18. Beiträge anzeigen #98 Zitieren
    Local Hero
    Registriert seit
    Feb 2013
    Beiträge
    236
     
    pawbuj ist offline
    @Fawkes,

    thank you, very good.

    have u also fix the bug with mobswitch state01 after save/load game? It causes the mover being stucked when mobswitch will be in position 1 (gate closed) while saving.

  19. Beiträge anzeigen #99 Zitieren
    Local Hero
    Registriert seit
    Feb 2017
    Beiträge
    270
     
    F a w k e s ist offline
    Zitat Zitat von pawbuj Beitrag anzeigen
    have u also fix the bug with mobswitch state01 after save/load game? It causes the mover being stucked when mobswitch will be in position 1 (gate closed) while saving.
    Hi pawbuj,
    uh oh, I personally did not encounter such an issue. Can you please tell us how to simply replicate this (ideally on G1 original version) in order to get an idea how to fix it?

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

    LeGo G1 Improved trading system

    Hello folks,
    Finally finished one I believe nifty feature for my small G1 mod - so wanted to share it in case someone else would find it usefull!
    Trading system in G1 is painfull. Below hook of oCViewDialogTrade__OnAccept will improve it a little-bit.
    As soon as you select what items you want to sell & buy you can hit Enter to Accept trade - you wont need to make the $ amount on both Trader's item container and Buyer's item container equal. Just confirm Accept trade.
    [Bild: gm_trade_en_01.png]

    Ore will be transferred automatically. (in case Trader / Buyer do have enough ore)
    [Bild: gm_trade_en_02.png]

    [Bild: gm_trade_en_03.png]

    Code:
    //Requires LeGo G1 [tested with LeGo 2.5.0]
    
    //[G1 addresses]
    //0072A870  .text     Debug data           ?OnAccept@oCViewDialogTrade@@IAIXXZ
    const int oCViewDialogTrade__OnAccept        = 7514224;
    
    //00729390  .text     Debug data           ?TransferAccept@oCViewDialogTrade@@IAIXXZ
    const int oCViewDialogTrade__TransferAccept    = 7508880;
    
    //'Cannibalized' from Ikarus 1.2 oCNpc class definition
    class oCItemContainer {
                var int    inventory2_vtbl;                                      // 0x0550 1360
                var int    inventory2_oCItemContainer_contents;                        // 0x0554 zCListSort<oCItem>*
                var int    inventory2_oCItemContainer_npc;                             // 0x0558 oCNpc*
                var int    inventory2_oCItemContainer_selectedItem;                    // 0x055C int
                var int    inventory2_oCItemContainer_offset;                          // 0x0560 int
                var int    inventory2_oCItemContainer_drawItemMax;                     // 0x0564 int
                var int    inventory2_oCItemContainer_itemListMode;                    // 0x0568 oTItemListMode
                var int    inventory2_oCItemContainer_frame;                           // 0x056C zBOOL
                var int    inventory2_oCItemContainer_right;                           // 0x0570 zBOOL
                var int    inventory2_oCItemContainer_ownList;                         // 0x0574 zBOOL
                var int    inventory2_oCItemContainer_prepared;                        // 0x0578 zBOOL
                var int    inventory2_oCItemContainer_passive;                         // 0x057C zBOOL
                var int    inventory2_oCItemContainer_viewCat;                         // 0x0580 zCView*
                var int    inventory2_oCItemContainer_viewItem;                        // 0x0584 zCView*
                var int    inventory2_oCItemContainer_viewItemActive;                  // 0x0588 zCView*
                var int    inventory2_oCItemContainer_viewItemHightlighted;            // 0x058C zCView*
                var int    inventory2_oCItemContainer_viewItemActiveHighlighted;       // 0x0590 zCView*
                var int    inventory2_oCItemContainer_viewItemFocus;                   // 0x0594 zCView*
                var int    inventory2_oCItemContainer_viewItemActiveFocus;             // 0x0598 zCView*
                var int    inventory2_oCItemContainer_viewItemHightlightedFocus;       // 0x059C zCView*
                var int    inventory2_oCItemContainer_viewItemActiveHighlightedFocus;  // 0x05A0 zCView*
                var int    inventory2_oCItemContainer_viewItemInfo;                    // 0x05A4 zCView*
                var int    inventory2_oCItemContainer_viewItemInfoItem;                // 0x05A8 zCView*
                var int    inventory2_oCItemContainer_textView;                        // 0x05AC zCView*
                var int    inventory2_oCItemContainer_viewArrowAtTop;                  // 0x05B0 zCView*
                var int    inventory2_oCItemContainer_viewArrowAtBottom;               // 0x05B4 zCView*
                var int    inventory2_oCItemContainer_rndWorld;                        // 0x05B8 zCWorld*
                var int    inventory2_oCItemContainer_posx;                            // 0x05BC int
                var int    inventory2_oCItemContainer_posy;                            // 0x05C0 int
                var string inventory2_oCItemContainer_textCategoryStatic;              // 0x05C4 zstring
                var int    inventory2_oCItemContainer_m_bManipulateItemsDisabled;      // 0x05D8 zBOOL
                var int    inventory2_oCItemContainer_m_bCanTransferMoreThanOneItem;   // 0x05DC zBOOL
                var int    inventory2_oCItemContainer_image_chroma;                    // 0x05E0 zCOLOR
                var int    inventory2_oCItemContainer_blit_chroma;                     // 0x05E4 zCOLOR
    //      }
            var int        inventory2_owner;                           // 0x05E8 oCNpc*
            var int        inventory2_packAbility;                     // 0x05EC zBOOL
    //      zCListSort<oCItem>[INV_MAX] inventory {
                var int    inventory2_inventory0_Compare;              // 0x05F0 int(_cdecl*)(oCItem*,oCItem*)
                var int    inventory2_inventory0_data;                 // 0x05F4 oCItem*
                var int    inventory2_inventory0_next;                 // 0x05F8 zCListSort<oCItem>*
                var int    inventory2_inventory1_Compare;              // 0x05FC int(_cdecl*)(oCItem*,oCItem*)
                var int    inventory2_inventory1_data;                 // 0x0600 oCItem*
                var int    inventory2_inventory1_next;                 // 0x0604 zCListSort<oCItem>*
                var int    inventory2_inventory2_Compare;              // 0x0608 int(_cdecl*)(oCItem*,oCItem*)
                var int    inventory2_inventory2_data;                 // 0x060C oCItem*
                var int    inventory2_inventory2_next;                 // 0x0610 zCListSort<oCItem>*
                var int    inventory2_inventory3_Compare;              // 0x0614 int(_cdecl*)(oCItem*,oCItem*)
                var int    inventory2_inventory3_data;                 // 0x0618 oCItem*
                var int    inventory2_inventory3_next;                 // 0x061C zCListSort<oCItem>*
                var int    inventory2_inventory4_Compare;              // 0x0620 int(_cdecl*)(oCItem*,oCItem*)
                var int    inventory2_inventory4_data;                 // 0x0624 oCItem*
                var int    inventory2_inventory4_next;                 // 0x0628 zCListSort<oCItem>*
                var int    inventory2_inventory5_Compare;              // 0x062C int(_cdecl*)(oCItem*,oCItem*)
                var int    inventory2_inventory5_data;                 // 0x0630 oCItem*
                var int    inventory2_inventory5_next;                 // 0x0634 zCListSort<oCItem>*
                var int    inventory2_inventory6_Compare;              // 0x0638 int(_cdecl*)(oCItem*,oCItem*)
                var int    inventory2_inventory6_data;                 // 0x063C oCItem*
                var int    inventory2_inventory6_next;                 // 0x0640 zCListSort<oCItem>*
                var int    inventory2_inventory7_Compare;              // 0x0644 int(_cdecl*)(oCItem*,oCItem*)
                var int    inventory2_inventory7_data;                 // 0x0648 oCItem*
                var int    inventory2_inventory7_next;                 // 0x064C zCListSort<oCItem>*
                var int    inventory2_inventory8_Compare;              // 0x0650 int(_cdecl*)(oCItem*,oCItem*)
                var int    inventory2_inventory8_data;                 // 0x0654 oCItem*
                var int    inventory2_inventory8_next;                 // 0x0658 zCListSort<oCItem>*
    //      }
            var string     inventory2_packstring;                      // 0x065C zstring[INV_MAX]
            var string     inventory2_packstring1;
            var string     inventory2_packstring2;
            var string     inventory2_packstring3;
            var string     inventory2_packstring4;
            var string     inventory2_packstring5;
            var string     inventory2_packstring6;
            var string     inventory2_packstring7;
            var string     inventory2_packstring8;
            var int        inventory2__offset[9];                      // 0x0710 int[INV_MAX]
            var int        inventory2__itemnr[9];                      // 0x0734 int[INV_MAX]
            var int        inventory2_maxSlots[9];                     // 0x0758 int[INV_MAX]
            var int        inventory2_invnr;                           // 0x077C int
    };
    
    FUNC VOID _HOOK_TRADE_ONACCEPT ()
    {
        var int ptr;
        
        var oCItemContainer Item_Container_Trader;
        var oCItemContainer Item_Container_Trader_Offer;
        var oCItemContainer Item_Container_Buyer_Offer;
        var oCItemContainer Item_Container_Buyer;
    
    //--- Get All 4 item containers (oCItemContainer)
    
        //Traders Inventory
        ptr = MEMINT_oCInformationManager_Address;
        ptr = MEM_ReadInt (ptr + 24);    //oCInformationManager.ocViewDialogTrade
        if (ptr) {
            ptr = MEM_ReadInt (ptr + 248);    //oCViewDialogItemInventory
            if (ptr) {
                ptr = MEM_ReadInt (ptr + 256);    //oCItemContainer
                Item_Container_Trader = _^ (ptr);
            };
        };
    
        //Traders 'offer'
        ptr = MEMINT_oCInformationManager_Address;
        ptr = MEM_ReadInt (ptr + 24);    //oCInformationManager.ocViewDialogTrade
        if (ptr) {
            ptr = MEM_ReadInt (ptr + 252);    //oCViewDialogStealContainer
            if (ptr) {
                ptr = MEM_ReadInt (ptr + 256);    //oCItemContainer
                Item_Container_Trader_Offer = _^ (ptr);
            };
        };
    
        //Buyers 'offer'
        ptr = MEMINT_oCInformationManager_Address;
        ptr = MEM_ReadInt (ptr + 24);    //oCInformationManager.ocViewDialogTrade
        if (ptr) {
            ptr = MEM_ReadInt (ptr + 260);    //oCViewDialogItemContainer
            if (ptr) {
                ptr = MEM_ReadInt (ptr + 256);    //oCItemContainer
                Item_Container_Buyer_Offer = _^ (ptr);
            };
        };
    
        //Buyers inventory
        ptr = MEMINT_oCInformationManager_Address;
        ptr = MEM_ReadInt (ptr + 24);    //oCInformationManager.ocViewDialogTrade
        if (ptr) {
            ptr = MEM_ReadInt (ptr + 264);    //oCViewDialogItemInventory
            if (ptr) {
                ptr = MEM_ReadInt (ptr + 256);    //oCItemContainer
                Item_Container_Buyer = _^ (ptr);
            };
        };
        
    //--- Get Offer Value + Ore amount for both Trader and Buyer
    
        var int Value_Traders_Offer;
        var int Value_Buyers_Offer;
    
        var int Ore_Trader;
        var int Ore_Buyer;
    
        var int Delta;
    
        //inventory2_oCItemContainer_textCategoryStatic contains Total Value of offers - we can exploit that
        Value_Traders_Offer = STR_ToInt (Item_Container_Trader_Offer.inventory2_oCItemContainer_textCategoryStatic);
        Value_Buyers_Offer = STR_ToInt (Item_Container_Buyer_Offer.inventory2_oCItemContainer_textCategoryStatic);
        
        var C_NPC Trader;
        Trader = _^ (Item_Container_Trader.inventory2_owner);
        Ore_Trader = NPC_HasItems (Trader, ItMiNugget);
        
        var C_NPC Buyer;
        Buyer = _^ (Item_Container_Buyer.inventory2_owner);
        Ore_Buyer = NPC_HasItems (Buyer, ItMiNugget);
        
        Delta = Value_Traders_Offer - Value_Buyers_Offer;
        
        var string msg;
        
        if (Delta == 0) {
            //Trade went smoothly :)
        } else
        //Buyer has to supply ore !
        if (Delta > 0) {
            if (Delta > Ore_Buyer) {
                PrintScreen_Ext ("Buyer does not have enough ore.", -1, _YPOS_MESSAGE_LOGENTRY, "font_old_20_white.tga", _TIME_MESSAGE_LOGENTRY);
            } else
            {
                //Accept Transfer anyway!
                ptr = MEMINT_oCInformationManager_Address;
                ptr = MEM_ReadInt (ptr + 24);    //oCInformationManager.ocViewDialogTrade
    
                CALL__thiscall (ptr, oCViewDialogTrade__TransferAccept);
    
                //'Move' ore from Buyer to Trader
                NPC_RemoveInvItems (Buyer, ItMiNugget, Delta);
                CreateInvItems (Trader, ItMiNugget, Delta);
                
                msg = ConcatStrings ("Ore transferred from Buyer: ", IntToString (Delta));
                PrintScreen_Ext (msg, -1, _YPOS_MESSAGE_LOGENTRY, "font_old_20_white.tga", _TIME_MESSAGE_LOGENTRY);
            };
        } else
        //Trader has to supply ore !
        {
            //Abs (Delta)
            Delta = 0 - Delta;
            
            if (Delta > Ore_Trader) {
                PrintScreen_Ext ("Trader does not have enough ore.", -1, _YPOS_MESSAGE_LOGENTRY, "font_old_20_white.tga", _TIME_MESSAGE_LOGENTRY);
            } else
            {
                //Accept Transfer anyway!
                ptr = MEMINT_oCInformationManager_Address;
                ptr = MEM_ReadInt (ptr + 24);    //oCInformationManager.ocViewDialogTrade
    
                CALL__thiscall (ptr, oCViewDialogTrade__TransferAccept);
    
                //'Move' ore from Trader to Buyer
                NPC_RemoveInvItems (Trader, ItMiNugget, Delta);
                CreateInvItems (Buyer, ItMiNugget, Delta);
                
                msg = ConcatStrings ("Ore transferred from Trader: ", IntToString (Delta));
                PrintScreen_Ext (msg, -1, _YPOS_MESSAGE_LOGENTRY, "font_old_20_white.tga", _TIME_MESSAGE_LOGENTRY);
            };
        };
    };
    Hook it with:
    HookEngine (oCViewDialogTrade__OnAccept, 6, "_HOOK_TRADE_ONACCEPT");

    I actually hope someone [I don't want to point my finger to anyone specific Lehona, Gottfried, Mud-Freak!] can improve this even further.
    Originally I didn't want to force trade by calling oCViewDialogTrade__TransferAccept and to move Ore from Buyer <- -> Trader directly.
    Idea was to move Ore from Item_Container_Buyer to Item_Container_Buyer_Offer in case Buyer would have to supply ore,
    or from Item_Container_Trader to Item_Container_Trader_Offer in case Trader would have to supply some ore.
    However I was not able to make this work flawlessly - I struggled with item transfers from inventory2_oCItemContainer_contents
    LeGo code is still out of my league!

Seite 5 von 27 « Erste 1234567891216 ... 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