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

 

Ergebnis 1 bis 19 von 19
  1. Homepage besuchen Beiträge anzeigen #1 Zitieren
    Team Velen
    Registriert seit
    Aug 2015
    Beiträge
    952
     
    Bloodfly91 ist offline

    Access Violation durch den Aufruf einer bestimmten Funktion in der Init_Global

    Hey,
    ich habe versucht, eine neue Funktion einzubauen, die dafür sorgt, dass dem Spieler unter bestimmten Voraussetzungen nach dem Laden eines Spielstandes direkt eine Fackel in die Hand gegeben wird. Allerdings erhalte ich durch den Aufruf dieser Funktion in der Init_Global beim Neubeginn des Spiels ständig eine AV-Meldung. Im zSpy steht dann folgendes:

    Code:
    00:20 Info:  0 Q:     LeGo 2.5.1 wurde erfolgreich initialisiert.
    00:20 Fault: 0 Q:     [start of stacktrace]
    00:20 Fault: 0 Q:             ASMINT_CALLMYEXTERNAL()                                        +    5 bytes
    00:20 Fault: 0 Q:             ASM_RUNONCE()                                                  +   77 bytes
    00:20 Fault: 0 Q:             CALLINT_MAKECALL(7544720, 0)                                   +  263 bytes
    00:20 Fault: 0 Q:             CALL__STDCALL(7544720)                                         +   21 bytes
    00:20 Fault: 0 Q:             CALL__THISCALL(0, 7544720)                                     +   73 bytes
    00:20 Fault: 0 Q:             BETTERTORCHES_GETSLOTITEM(1620, 'ZS_LEFTHAND')                 +   79 bytes
    00:20 Fault: 0 Q:             BETTERTORCHES_GIVEPLAYERTORCH()                                +   31 bytes
    00:20 Fault: 0 Q:             INIT_GLOBAL()                                                  +   31 bytes
    00:20 Fault: 0 Q:     [end of stacktrace]
    00:20 Fault: 0 Q:     Exception handler was invoked. Ikarus tried to print a Daedalus-Stacktrace to zSpy. Gothic will now crash and probably give you a stacktrace of its own.
    
    
    [...]
    
    
    00:25 Warn:  0 ==    ===================================== UNHANDLED EXCEPTION OCCURED ====================================================== .... <zError.cpp,#474>
    00:25 Warn:  0 ==    ============================================ CRASH INFOS: ============================================================== .... <zError.cpp,#474>
    00:25 Warn:  0 Go    thic II - 2.6 (fix), Parser Version: 50 .... <zError.cpp,#474>
    00:25 Warn:  0 Us    er:  ---,  CPUType: 586,  Mem: 2048 MB total, 2048 MB free .... <zError.cpp,#474>
    00:25 Warn:  0 St    artup Options: .... <zWin32.cpp,#2976>
    00:25 Warn:  0 -g    ame:torgan.ini -zreparse -zlog:10,s
     .... <zWin32.cpp,#2977>
    00:25 Warn:  0 ==    ============================================= CALLSTACK : ============================================================== .... <zError.cpp,#474>
    00:25 Warn:  0 00    23:00731F95 (0x00AB4108 0x00000000 0x00AB40C0 0x000015BF) Gothic2.exe, oCNpc::GetSlotItem()+5 byte(s), P:\dev\g2addon\release\Gothic\_ulf\oNpc.cpp, line 2645 .... <zError.cpp,#474>
    00:25 Warn:  0 00    23:00792568 (0x0000135E 0x00AB4108 0x00000000 0x00AB40C0) Gothic2.exe, zCParser::DoStack()+3080 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1433 .... <zError.cpp,#474>
    00:25 Warn:  0 00    23:00792504 (0x00001572 0x00AB4108 0x00000000 0x00AB40C0) Gothic2.exe, zCParser::DoStack()+2980 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1415 .... <zError.cpp,#474>

    Die Hauptfunktion, die auch in der Init_Global aufgerufen wird:

    Code:
    func void BetterTorches_GivePlayerTorch()
    {
    	if (GOTHIC_BASE_VERSION != 1)
    	{
    		var int ptr; ptr = BetterTorches_GetSlotItem (hero, "ZS_LEFTHAND");
    
    
    		if ((BetterTorches_Torch) && (!ptr))
    		{
    			BetterTorches_Equip (hero, ItLsTorchBurning);
    			
    			if (Npc_HasItems (hero, ItLsTorch) > 0)
    			{
    				Npc_RemoveInvItem (hero, ItLsTorch);
    			};
    		};
    	};
    };

    Verantwortlich für die AV ist wohl aber diese:

    Code:
    func int BetterTorches_GetSlotItem (var int slfInstance, var string slotName) 
    {
    	var C_NPC slf; slf = Hlp_GetNpc (slfInstance);
    
    
        CALL_zStringPtrParam (slotName);
        CALL__thiscall (_@ (slfInstance), MEMINT_SwitchG1G2(6878448, 7544720));
    
    
        return CALL_RetValAsPtr ();
    };

    Ich hatte erst die Vermutung, dass es eventuell an MEMINT_Switch liegt und nahm dieses deshalb auch schon raus, das war allerdings scheinbar nicht der Auslöser.

    Seltsamerweise stürzt es auch beim ersten Neubeginn des Spiels nach Spielstart nicht ab, wenn ich die Funktion in der Init_Global per FF_ApplyOnceExt einmalig aufrufe, dann funktioniert das Laden eines vorherigen Spielstandes aus irgendeinem Grund nicht mehr. Auch erhalte ich spätestens beim zweiten Neubeginn dann die AV.

    Der Aufruf in der Init_Global sieht so aus:

    Code:
    func void INIT_GLOBAL()
    {
    	// wird fuer jede Welt aufgerufen (vor INIT_<LevelName>)
    	Game_InitGerman();
    	
    	// LeGo & Ikarus
    	MEM_InitAll();
    	LeGo_Init(LeGo_All | LeGo_Buffs);
    	
    	BetterTorches_GivePlayerTorch();
    };

    Beziehungsweise mit Framefunction so:


    Code:
    func void INIT_GLOBAL()
    {
    	// wird fuer jede Welt aufgerufen (vor INIT_<LevelName>)
    	Game_InitGerman();
    	
    	// LeGo & Ikarus
    	MEM_InitAll();
    	LeGo_Init(LeGo_All | LeGo_Buffs);
    
    
    	FF_ApplyOnceExt(BetterTorches_GivePlayerTorch, 0, 1);
    };

    Weiß jemand, wo hier der Fehler liegt?

  2. Beiträge anzeigen #2 Zitieren
    Dea
    Registriert seit
    Jul 2007
    Beiträge
    10.447
     
    Lehona ist offline
    Code:
    00:20 Fault: 0 Q:             CALL__THISCALL(0, 7544720)
    Der Pointer, der an die Funktion übergeben wird, ist 0, was dann zu einem Absturz führt. Rein um komischen Fehlern vorzubeugen würde ich an BetterTorches_GetSlotItem keine Instanz sondern direkt den Pointer übergeben (d.h. das _@() aus BetterTorches_GetSlotItem entfernen und stattdessen die Funktion direkt mit _@(hero) aufrufen).

    Grundsätzlich gibt es meines Wissens aber Probleme mit der Existenz des Helden während der Init-Funktionen (daher rufst du das ganze ja auch schon verzögert auf). Da würd ich einfach mal eine höhere Verzögerung ausprobieren, z.B. 200ms. "Schön" machen kann man es dann, wenn es funktioniert.

    Auch erinnere ich mich an einen Post von mud-freak, der sagt, dass entweder PC_Hero oder hero nach einem Weltenwechsel nicht unbedingt korrekt initialisiert ist. Leider kann ich mich nicht mehr erinnern, welche der beiden Varianten die richtige war Wenn ich raten müsste, würde ich allerdings auch hero sagen. Dennoch etwas, was man ausprobieren könnte.

  3. Homepage besuchen Beiträge anzeigen #3 Zitieren
    Team Velen
    Registriert seit
    Aug 2015
    Beiträge
    952
     
    Bloodfly91 ist offline
    Zitat Zitat von Lehona Beitrag anzeigen
    Code:
    00:20 Fault: 0 Q:             CALL__THISCALL(0, 7544720)
    Der Pointer, der an die Funktion übergeben wird, ist 0, was dann zu einem Absturz führt. Rein um komischen Fehlern vorzubeugen würde ich an BetterTorches_GetSlotItem keine Instanz sondern direkt den Pointer übergeben (d.h. das _@() aus BetterTorches_GetSlotItem entfernen und stattdessen die Funktion direkt mit _@(hero) aufrufen).

    Grundsätzlich gibt es meines Wissens aber Probleme mit der Existenz des Helden während der Init-Funktionen (daher rufst du das ganze ja auch schon verzögert auf). Da würd ich einfach mal eine höhere Verzögerung ausprobieren, z.B. 200ms. "Schön" machen kann man es dann, wenn es funktioniert.

    Auch erinnere ich mich an einen Post von mud-freak, der sagt, dass entweder PC_Hero oder hero nach einem Weltenwechsel nicht unbedingt korrekt initialisiert ist. Leider kann ich mich nicht mehr erinnern, welche der beiden Varianten die richtige war Wenn ich raten müsste, würde ich allerdings auch hero sagen. Dennoch etwas, was man ausprobieren könnte.
    Vielen Dank, Lehona. Leider funktioniert es aber weiterhin nur beim ersten Neubeginn eines Spiels, seltsamerweise aber immer, wenn ich einen Spielstand lade.
    Die AV sieht nun aber etwas anders aus:

    Code:
    00:57 Warn:  0 ==  ===================================== UNHANDLED EXCEPTION OCCURED ====================================================== .... <zError.cpp,#474>00:57 Warn:  0 ==  ============================================ CRASH INFOS: ============================================================== .... <zError.cpp,#474>
    00:57 Warn:  0 Go  thic II - 2.6 (fix), Parser Version: 50 .... <zError.cpp,#474>
    00:57 Warn:  0 Us  er:  ---,  CPUType: 586,  Mem: 2048 MB total, 2048 MB free .... <zError.cpp,#474>
    00:57 Warn:  0 St  artup Options: .... <zWin32.cpp,#2976>
    00:57 Warn:  0 -g  ame:gothicgame.ini
     .... <zWin32.cpp,#2977>
    00:58 Warn:  0 ==  ============================================= CALLSTACK : ============================================================== .... <zError.cpp,#474>
    00:58 Warn:  0 00  23:00731F95 (0x00AB4108 0x00000000 0x00AB40C0 0x00226519) Gothic2.exe, oCNpc::GetSlotItem()+5 byte(s), P:\dev\g2addon\release\Gothic\_ulf\oNpc.cpp, line 2645 .... <zError.cpp,#474>
    00:58 Warn:  0 00  23:00792568 (0x00AB40C0 0x00000000 0x254A6FEC 0x00792955) Gothic2.exe, zCParser::DoStack()+3080 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1433 .... <zError.cpp,#474>
    00:58 Warn:  0 00  23:647385A4 (0x254A7010 0x00AB4118 0x00AB40C0 0x0135F390) dmstyle.dll .... <zError.cpp,#474>
    00:58 Warn:  0 00  23:00792955 (0x002262B8 0x00AB4108 0x00000000 0x00AB40C0) Gothic2.exe, zSTRING::zSTRING()+133 byte(s), ..\\ZenGin\_bert\zstring.h, line 94+133 byte(s) .... <zError.cpp,#474>
    00:58 Warn:  0 00  23:00792504 (0x002264CC 0x00AB4108 0x00000000 0x00AB40C0) Gothic2.exe, zCParser::DoStack()+2980 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1415 .... <zError.cpp,#474>
    00:58 Warn:  0 00  23:00792504 (0x00226AC1 0x00AB4108 0x00000000 0x00AB40C0) Gothic2.exe, zCParser::DoStack()+2980 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1415 .... <zError.cpp,#474>
    00:58 Warn:  0 00  23:00792504 (0x00226BC9 0x00AB4108 0x00000000 0x00AB40C0) Gothic2.exe, zCParser::DoStack()+2980 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1415 .... <zError.cpp,#474>
    00:58 Warn:  0 00  23:00792504 (0x00226BF5 0x00AB4108 0x00000000 0x00AB40C0) Gothic2.exe, zCParser::DoStack()+2980 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1415 .... <zError.cpp,#474>
    00:58 Warn:  0 00  23:00792504 (0x002540E1 0x00AB4108 0x00000000 0x00AB40C0) Gothic2.exe, zCParser::DoStack()+2980 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1415 .... <zError.cpp,#474>
    00:58 Warn:  0 00  23:00792504 (0x0025435D 0x00AB4108 0x00000000 0x00AB40C0) Gothic2.exe, zCParser::DoStack()+2980 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1415 .... <zError.cpp,#474>
    00:58 Warn:  0 00  23:00792504 (0x00225A52 0x00AB4108 0x00000000 0x00AB40C0) Gothic2.exe, zCParser::DoStack()+2980 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1415 .... <zError.cpp,#474>
    00:58 Warn:  0 00  23:00792504 (0x00228B9E 0x256AECE0 0x00AB4118 0x00AB40C0) Gothic2.exe, zCParser::DoStack()+2980 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1415 .... <zError.cpp,#474>
    00:58 Warn:  0 00  23:00792504 (0x00230E00 0x0135F7F8 0x00000000 0x0135FC90) Gothic2.exe, zCParser::DoStack()+2980 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1415 .... <zError.cpp,#474>
    00:58 Warn:  0 00  23:00792CBF (0x00000000 0x0135F7F8 0x00AB40C0 0x1AA89008) Gothic2.exe, zCParser::CallFunc()+719 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1551 .... <zError.cpp,#474>
    00:58 Warn:  0 00  23:0042B9E8 (0x00000000 0x00792568 0x1A92C78C 0x00AB4118) Gothic2.exe, CGameManager::PlayVideo()+168 byte(s), P:\dev\g2addon\release\Gothic\_bert\oGameManager.cpp, line 1969 .... <zError.cpp,#474>
    00:58 Warn:  0 00  23:0081B6D8 (0x3924A340 0x0135F9C0 0x0C946CC0 0xFFFFFFFF) Gothic2.exe, SetFileAttributesA()+228116 byte(s) .... <zError.cpp,#474>
    00:58 Warn:  0 00  23:0040317B (0x006D45B0 0x008B23B3 0x0082E6F0 0x0C913E90) Gothic2.exe, std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Grow()+251 byte(s), P:\vs6\VC98\INCLUDE\xstring, line 569+17 byte(s) .... <zError.cpp,#474>
    00:58 Warn:  0 00  23:00792CBF (0x0135FA90 0x00800E8B 0x0082E6F0 0x0046F400) Gothic2.exe, zCParser::CallFunc()+719 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1551 .... <zError.cpp,#474>
    00:58 Warn:  0 00  23:66A41A56 (0x00000000 0x00000000 0x00000000 0x00000000) SHW32.DLL, shi_malloc()+22 byte(s) .... <zError.cpp,#474>
    00:58 Warn:  0 ==  ===================================== UNHANDLED EXCEPTION OCCURED ====================================================== .... <zError.cpp,#474>
    01:08 Warn:  0 B:   GMAN: gameSession is existing. Call CGameManager::Done() before! .... <oGameManager.cpp,#375>
    01:08 Info:  1 B:   VFILE: Deinitializing filesystem (VDFS) .... <zDisk_Vdfs.cpp,#619>
    01:08 Info:  2 B:   zDSK: 0 files were simultanously open! .... <zDisk_Vdfs.cpp,#625>

  4. Beiträge anzeigen #4 Zitieren
    Knight
    Registriert seit
    Aug 2009
    Ort
    Hessen
    Beiträge
    1.487
     
    Cryp18Struct ist offline
    Zitat Zitat von Lehona Beitrag anzeigen
    Auch erinnere ich mich an einen Post von mud-freak, der sagt, dass entweder PC_Hero oder hero nach einem Weltenwechsel nicht unbedingt korrekt initialisiert ist. Leider kann ich mich nicht mehr erinnern, welche der beiden Varianten die richtige war Wenn ich raten müsste, würde ich allerdings auch hero sagen. Dennoch etwas, was man ausprobieren könnte.
    PC_HERO ist nach Weltwechsel nicht korrekt initialisiert:
    https://forum.worldofplayers.de/foru...ge4?p=25742896

    Zitat Zitat von Bloodfly91 Beitrag anzeigen
    Vielen Dank, Lehona. Leider funktioniert es aber weiterhin nur beim ersten Neubeginn eines Spiels, seltsamerweise aber immer, wenn ich einen Spielstand lade.
    Die AV sieht nun aber etwas anders aus:
    [...]
    Du könntest mal so eine Struktur probieren:
    Code:
    func void BetterTorches_GivePlayerTorch()
    {
    	if(! Hlp_IsValidNpc(hero)){
    		printDebug("hero not valid, skip 1 frame");
    		return; // Aus der Funktion springen. FF läuft weiter und nächsten frame wird es erneut probiert.
    	};
    	
    	// Hier könnte man jetzt noch mehr if(X)[return;}; Sachen reinbauen(prüfen ob visual ungültig?...)
    	
    	printDebug("hero is valid");
    	if (GOTHIC_BASE_VERSION != 1)
    	{
    		var int ptr; ptr = BetterTorches_GetSlotItem (hero, "ZS_LEFTHAND");
    
    
    		if ((BetterTorches_Torch) && (!ptr))
    		{
    			BetterTorches_Equip (hero, ItLsTorchBurning);
    			
    			if (Npc_HasItems (hero, ItLsTorch) > 0)
    			{
    				Npc_RemoveInvItem (hero, ItLsTorch);
    			};
    		};
    	};
    
    	FF_Remove(BetterTorches_GivePlayerTorch); // Nur nachdem der code erfolgreich ausgeführt wurde die FF löschen
    };
    Code:
    func void INIT_GLOBAL()
    {
    	// wird fuer jede Welt aufgerufen (vor INIT_<LevelName>)
    	Game_InitGerman();
    	
    	// LeGo & Ikarus
    	MEM_InitAll();
    	LeGo_Init(LeGo_All | LeGo_Buffs);
    
    
    	FF_ApplyOnce(BetterTorches_GivePlayerTorch); // Funktion jeden frame aufrufen, löscht sich später selbst
    };

  5. Beiträge anzeigen #5 Zitieren
    Dea
    Registriert seit
    Jul 2007
    Beiträge
    10.447
     
    Lehona ist offline
    Gibt es diesmal keinen Daedalus-Stacktrace? Aus der AV werde ich so auf die Schnelle nicht schlau, zumal irgendwo bei der Ausführung der Stack kaputt gegangen sein muss.

    Habe allerdings mal in die entsprechende Funktion (oCNpc::GetSlotItem(zString*)) reingeschaut und an +5 Bytes wird auf npc.invSlot_numInArray zugegriffen, was zu dem Absturz führt. Klingt für mich so, als würde der Pointer noch immer nicht stimmen. Was passiert, wenn du BetterTorches_GivePlayerTorch() vor dem Weltenwechsel ausführst, also nicht in einer INIT_* oder STARTUP_* Funktion? An dieser Stelle sollte zumindest hero noch verlässlich initialisiert sein.

    Und nur der Vollständigkeit halber solltest du auch nochmal deinen angepassten Code zeigen, einfach nur um Missverständnissen aus dem Weg zu gehen

    Edit: Der Code von Crypt18Struct übergibt übrigens hero noch als Instanz, das passt nicht mehr zu deiner Version von BetterTorches_GetSlotItem, falls du meine vorgeschlagene Änderung durchgeführt hast. Also eine der beiden Stellen anpassen

  6. Homepage besuchen Beiträge anzeigen #6 Zitieren
    Team Velen
    Registriert seit
    Aug 2015
    Beiträge
    952
     
    Bloodfly91 ist offline
    Danke, ich habe nun mal den Vorschlag von Cryp18Struct versucht, natürlich vorher angepasst, die AV erscheint aber trotzdem wieder. Allerdings habe ich festgestellt, dass es mit der Änderung von vorhin, also direkt den Pointer übergeben, als "normales" Skript mit meiner Modding-Installation scheinbar nun funktioniert. Nur als Ninja-Patch, was es eigentlich werden soll, scheint nun diese AV aufzutreten. Die Funktion erst vor dem Weltenwechsel auszuführen, scheint unter anderem deshalb auch nicht einfach möglich zu sein. Mittlerweile denke ich aber, dass zumindest die jetzige AV eventuell eher ein Problem mit Ninja direkt ist.

    Hier trotzdem nochmal der momentane Code, eventuell ist ja doch noch irgendwo ein Fehler:

    Code:
    func int BetterTorches_GetSlotItem (var string slotName) {
    	CALL_zStringPtrParam (slotName);
        CALL__thiscall (_@(hero), MEMINT_SwitchG1G2(6878448, 7544720));
    
    
        return CALL_RetValAsPtr ();
    };
    Code:
    func void BetterTorches_GivePlayerTorch()
    {
    	if(!Hlp_IsValidNpc(hero))
    	{
    		printDebug("[BetterTorches] Hero not valid, skip 1 frame!");
    		
    		return;
    	};
    	
    	printDebug("[BetterTorches] Hero is valid!");
    	
    	if (GOTHIC_BASE_VERSION != 1)
    	{
    		var int ptr; ptr = BetterTorches_GetSlotItem ("ZS_LEFTHAND");
    
    
    		if ((BetterTorches_Torch) && (!ptr))
    		{
    			BetterTorches_Equip ();
    			
    			if (Npc_HasItems (hero, ItLsTorch) > 0)
    			{
    				Npc_RemoveInvItem (hero, ItLsTorch);
    			};
    		};
    	};
    
    
    	FF_Remove(BetterTorches_GivePlayerTorch);
    };

    BetterTorches_Equip(); habe ich auch etwas angepasst, da diese Funktion ja nur für die Fackeln benötigt wird. Aber das sollte nicht die AV auslösen, denn das funktioniert ebenfalls mit der Modding-Installation:

    Code:
    FUNC VOID BetterTorches_Equip (){
    	if (Npc_HasItems (hero, ItLsTorch) < 1)
        {
    		CreateInvItem (hero, ItLsTorch);
        };
    	
        CALL_PtrParam (_@(ItLsTorchBurning));
        CALL__thiscall (_@(hero), MEMINT_SwitchG1G2(6908144, 7576720));
    };

  7. Beiträge anzeigen #7 Zitieren
    Dea
    Registriert seit
    Jul 2007
    Beiträge
    10.447
     
    Lehona ist offline
    Was steht denn im zSpy? Die PrintDebug-Aufrufe von Cryp18Struct sollten dort auftauchen, eventuell musst du das allerdings vorher aktivieren via MEM_SetShowDebug(true).

  8. Homepage besuchen Beiträge anzeigen #8 Zitieren
    Team Velen
    Registriert seit
    Aug 2015
    Beiträge
    952
     
    Bloodfly91 ist offline
    Zitat Zitat von Lehona Beitrag anzeigen
    Was steht denn im zSpy? Die PrintDebug-Aufrufe von Cryp18Struct sollten dort auftauchen, eventuell musst du das allerdings vorher aktivieren via MEM_SetShowDebug(true).
    Im zSpy wird "Hero is valid!" angezeigt, die Invalid-Meldung gar nicht. Ich habe mal diese und einige der vorherigen zSpy-Meldungen herauskopiert (Originalspiel inklusive dem Skript als Ninja-Patch):

    Code:
    -4-    00:13 Info:  2 U:     AI: Inserted NPC : Xardas / NONE_100_XARDAS .... <oNpc.cpp,#9188>
    -4-    00:13 Info:  1 B:     GMAN: Completed loading the world ... .... <oGameManager.cpp,#1476>
    -4-    00:13 Info:  3 B:     OPT: Applying settings ... .... <oGameManager.cpp,#1178>
    -4-    00:13 Info:  3 B:       OPT: Lookaround inverse = 0 .... <oGameManager.cpp,#1221>
    -4-    00:13 Info:  3 B:       OPT: Music-Volume: Value=0.866666675 .... <oGameManager.cpp,#1233>
    -4-    00:13 Info:  3 B:       OPT: Sound-Volume: Value=1 .... <oGameManager.cpp,#1234>
    -4-    00:13 Info:  3 B:       OPT: Mouse-Enabled = 1 .... <oGameManager.cpp,#1240>
    -4-    00:13 Info:  3 B:       OPT: Mouse-Sensitivity = 0.550000012 .... <oGameManager.cpp,#1241>
    -4-    00:13 Info:  3 B:       OPT: Level-Sight: Value=300, resulting factor=9 .... <oGameManager.cpp,#1251>
    -4-    00:13 Info:  3 B:       OPT: Vob-Sight: Value=14 .... <oGameManager.cpp,#1254>
    -4-    00:13 Info:  3 B:       OPT: Sky: Value=1 .... <oGameManager.cpp,#1271>
    -4-    00:13 Info:  3 B:       OPT: Model-Details: Value=1 .... <oGameManager.cpp,#1294>
    -4-    00:13 Info:  3 B:       OPT: Blood-Details: Value=3 .... <oGameManager.cpp,#1302>
    -4-    00:13 Info:  3 B:     GMAN: Leaving Menu-Section .... <oGameManager.cpp,#1537>
    -4-    00:13 Info:  4 B:     GMAN: Close InitScreen .... <oGameManager.cpp,#849>
    -4-    00:13 Info:  0 Q:     Locals: Install at _HOOK
    -4-    00:13 Info:  0 Q:             Offset is 70
    -4-    00:13 Info:  5 U:    Skript: [BetterTorches] Hero is valid! .... <zError.cpp,#465>
    -4-    00:15 Info:  5 X:     ProcessZoneList: musiczone changed - try to start new themeXAR_DAY_STD .... <zError.cpp,#465>
    -4-    00:15 Info:  5 X:     [LoadThemeByScript]: loading theme:XAR_DAY_STD .... <zMusic_Dm.cpp,#519>

  9. Beiträge anzeigen #9 Zitieren
    Dea
    Registriert seit
    Jul 2007
    Beiträge
    10.447
     
    Lehona ist offline
    Okay, dann scheint hero wohl richtig initialisiert zu sein. Bist du dir ganz sicher, dass sich die AV nicht geändert hat? Fackeln haben auch einige Sonderbehandlungen in der Engine, vielleicht könntest du testweise erstmal ein Schwert oder so in die Hand legen? Auch wenn es für mich so aussieht, als würde der Code gar nicht so weit kommen. Nur sicherheitshalber könntest du auch nochmal den Wert _@(hero) im zSpy ausgeben lassen.

    Wenn du BetterTorches_GivePlayerTorch() nicht ausführst oder nur irgendwas mundanes darin machst (z.B. ein Print) funktioniert der Ninja-Patch, ja?

  10. Homepage besuchen Beiträge anzeigen #10 Zitieren
    Team Velen
    Registriert seit
    Aug 2015
    Beiträge
    952
     
    Bloodfly91 ist offline
    Zitat Zitat von Lehona Beitrag anzeigen
    Okay, dann scheint hero wohl richtig initialisiert zu sein. Bist du dir ganz sicher, dass sich die AV nicht geändert hat? Fackeln haben auch einige Sonderbehandlungen in der Engine, vielleicht könntest du testweise erstmal ein Schwert oder so in die Hand legen? Auch wenn es für mich so aussieht, als würde der Code gar nicht so weit kommen. Nur sicherheitshalber könntest du auch nochmal den Wert _@(hero) im zSpy ausgeben lassen.

    Wenn du BetterTorches_GivePlayerTorch() nicht ausführst oder nur irgendwas mundanes darin machst (z.B. ein Print) funktioniert der Ninja-Patch, ja?
    Hm, tatsächlich funktioniert der Patch nach der Änderung, den Pointer direkt zu übergeben, auch nicht mehr, wenn ich die Funktion auskommentiere oder in dieser nur einen Print ausgeben lasse. BetterTorches_GetSlotItem scheint nun also auch in anderen Funktionen mit dieser Änderung Probleme zu bereiten. Allerdings nur als Ninja-Patch. Als normales Skript scheint es ja problemlos zu funktionieren. Auch habe ich mal die Fackel durch ein Schwert ersetzt, das in die Hand gegeben wird, das Problem besteht weiterhin.
    Ich kann mir das nicht erklären. Vor allem, da es immer erst auftritt, wenn ich nach einem Neubeginn erneut einen Neubeginn des Spiels starte.

    Die aktuelle Fehlermeldung lautet:

    Code:
    00:32 Warn:  0 ==      ===================================== UNHANDLED EXCEPTION OCCURED ====================================================== .... <zError.cpp,#474>00:32 Warn:  0 ==      ============================================ CRASH INFOS: ============================================================== .... <zError.cpp,#474>
    00:32 Warn:  0 Go      thic II - 2.6 (fix), Parser Version: 50 .... <zError.cpp,#474>
    00:32 Warn:  0 Us      er:  ---,  CPUType: 586,  Mem: 2048 MB total, 2048 MB free .... <zError.cpp,#474>
    00:32 Warn:  0 St      artup Options: .... <zWin32.cpp,#2976>
    00:32 Warn:  0 -g      ame:GothicGame.ini -zlog:4,s
     .... <zWin32.cpp,#2977>
    00:32 Warn:  0 ==      ============================================= CALLSTACK : ============================================================== .... <zError.cpp,#474>
    00:32 Warn:  0 00      23:00731F95 (0x00AB4108 0x00000000 0x00AB40C0 0x00226519) Gothic2.exe, oCNpc::GetSlotItem()+5 byte(s), P:\dev\g2addon\release\Gothic\_ulf\oNpc.cpp, line 2645 .... <zError.cpp,#474>
    00:32 Warn:  0 00      23:00792568 (0x00AB40C0 0x00000000 0x27C66BFC 0x00792955) Gothic2.exe, zCParser::DoStack()+3080 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1433 .... <zError.cpp,#474>
    00:32 Warn:  0 00      23:5C6285A4 (0x27C66C20 0x00AB4118 0x00AB40C0 0x0135F390) dmstyle.dll .... <zError.cpp,#474>
    00:32 Warn:  0 00      23:00792955 (0x002262B8 0x00AB4108 0x00000000 0x00AB40C0) Gothic2.exe, zSTRING::zSTRING()+133 byte(s), ..\\ZenGin\_bert\zstring.h, line 94+133 byte(s) .... <zError.cpp,#474>
    00:32 Warn:  0 00      23:00792504 (0x002264CC 0x00AB4108 0x00000000 0x00AB40C0) Gothic2.exe, zCParser::DoStack()+2980 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1415 .... <zError.cpp,#474>
    00:32 Warn:  0 00      23:00792504 (0x00226AC1 0x00AB4108 0x00000000 0x00AB40C0) Gothic2.exe, zCParser::DoStack()+2980 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1415 .... <zError.cpp,#474>
    00:32 Warn:  0 00      23:00792504 (0x00226BC9 0x00AB4108 0x00000000 0x00AB40C0) Gothic2.exe, zCParser::DoStack()+2980 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1415 .... <zError.cpp,#474>
    00:32 Warn:  0 00      23:00792504 (0x00226BF5 0x00AB4108 0x00000000 0x00AB40C0) Gothic2.exe, zCParser::DoStack()+2980 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1415 .... <zError.cpp,#474>
    00:32 Warn:  0 00      23:00792504 (0x002466A4 0x00AB4108 0x00000000 0x00AB40C0) Gothic2.exe, zCParser::DoStack()+2980 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1415 .... <zError.cpp,#474>
    00:32 Warn:  0 00      23:00792504 (0x00246959 0x00AB4108 0x00000000 0x00AB40C0) Gothic2.exe, zCParser::DoStack()+2980 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1415 .... <zError.cpp,#474>
    00:32 Warn:  0 00      23:00792504 (0x00225A52 0x00AB4108 0x00000000 0x00AB40C0) Gothic2.exe, zCParser::DoStack()+2980 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1415 .... <zError.cpp,#474>
    00:32 Warn:  0 00      23:00792504 (0x00228B9E 0x27D8DAF8 0x00AB4118 0x00AB40C0) Gothic2.exe, zCParser::DoStack()+2980 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1415 .... <zError.cpp,#474>
    00:32 Warn:  0 00      23:00792504 (0x00230E00 0x0135F7F8 0x00000000 0x0135FC90) Gothic2.exe, zCParser::DoStack()+2980 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1415 .... <zError.cpp,#474>
    00:32 Warn:  0 00      23:00792CBF (0x00000000 0x0135F7F8 0x00AB40C0 0x1B165008) Gothic2.exe, zCParser::CallFunc()+719 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1551 .... <zError.cpp,#474>
    00:32 Warn:  0 00      23:0042B9E8 (0x00000000 0x00792568 0x1B00878C 0x00AB4118) Gothic2.exe, CGameManager::PlayVideo()+168 byte(s), P:\dev\g2addon\release\Gothic\_bert\oGameManager.cpp, line 1969 .... <zError.cpp,#474>
    00:32 Warn:  0 00      23:0081B6D8 (0x323F0838 0x0135F9C0 0x33DAE800 0xFFFFFFFF) Gothic2.exe, SetFileAttributesA()+228116 byte(s) .... <zError.cpp,#474>
    00:32 Warn:  0 00      23:0040317B (0x006D45B0 0x008B23B3 0x0082E6F0 0x0C6078B0) Gothic2.exe, std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Grow()+251 byte(s), P:\vs6\VC98\INCLUDE\xstring, line 569+17 byte(s) .... <zError.cpp,#474>
    00:32 Warn:  0 00      23:00792CBF (0x0135FA90 0x00800E8B 0x0082E6F0 0x0046F400) Gothic2.exe, zCParser::CallFunc()+719 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1551 .... <zError.cpp,#474>
    00:32 Warn:  0 00      23:5E621A56 (0x00000000 0x00000000 0x00000000 0x00000000) SHW32.DLL, shi_malloc()+22 byte(s) .... <zError.cpp,#474>
    00:32 Warn:  0 ==      ===================================== UNHANDLED EXCEPTION OCCURED ====================================================== .... <zError.cpp,#474>
    00:35 Warn:  0 B:       GMAN: gameSession is existing. Call CGameManager::Done() before! .... <oGameManager.cpp,#375>
    00:35 Info:  1 B:       VFILE: Deinitializing filesystem (VDFS) .... <zDisk_Vdfs.cpp,#619>
    Weitere Informationen werden mir leider nicht mehr angezeigt.

    Dumme Frage: Wie kann ich denn diesen _@(hero)-Wert per PrintDebug anzeigen lassen?

  11. Beiträge anzeigen #11 Zitieren
    Dea
    Registriert seit
    Jul 2007
    Beiträge
    10.447
     
    Lehona ist offline
    Naja da kommt auch einfach nur ein Integer raus, also IntToString und los geht's

    Ich denk morgen nochmal drüber nach, was da schief gegangen sein könnte.

  12. Homepage besuchen Beiträge anzeigen #12 Zitieren
    Team Velen
    Registriert seit
    Aug 2015
    Beiträge
    952
     
    Bloodfly91 ist offline
    Zitat Zitat von Lehona Beitrag anzeigen
    Naja da kommt auch einfach nur ein Integer raus, also IntToString und los geht's

    Ich denk morgen nochmal drüber nach, was da schief gegangen sein könnte.
    Alles klar, ich habe nun mal einen Print dafür eingebaut. Der Wert scheint allerdings korrekt zu sein. Sobald der Absturz auftritt, wird dieser Print allerdings gar nicht in zSpy angezeigt. Die Prints von Cryp18Struct in der BetterTorches_GivePlayerTorch-Funktion aber auch nicht.
    Da in der neuen AV ja unter anderem zString erwähnt wurde, versuchte ich einfach mal, diesen ohnehin eigentlich für mein Vorhaben sinnlosen String-Parameter für den Slot, der überprüft werden soll, aus der BetterTorches_GetSlotItem-Funktion zu entfernen. Nun erscheint allerdings WIEDER eine andere AV...

    Code:
    [w] 00:23 Warn:  0 X:       [RND3D-Destructor]: Can't uninitialize D3DX Utility Library ! Error: D3DXERR_D3DXNOTSTARTEDYET .... <zRndD3D.h,#127>[i] 00:23 Info:  5 X:       [RND3D-Destructor]: D3DXUninitialize done .... <zRndD3D_Render.cpp,#309>
    [w] 00:24 Warn:  0 ==      ===================================== UNHANDLED EXCEPTION OCCURED ====================================================== .... <zError.cpp,#474>
    [w] 00:24 Warn:  0 ==      ============================================ CRASH INFOS: ============================================================== .... <zError.cpp,#474>
    [w] 00:24 Warn:  0 Go      thic II - 2.6 (fix), Parser Version: 50 .... <zError.cpp,#474>
    [w] 00:24 Warn:  0 Us      er:  ---,  CPUType: 586,  Mem: 2048 MB total, 2048 MB free .... <zError.cpp,#474>
    [w] 00:24 Warn:  0 St      artup Options: .... <zWin32.cpp,#2976>
    [w] 00:24 Warn:  0 -g      ame:GothicGame.ini -zlog:4,s
    
    
     .... <zWin32.cpp,#2977>
    [w] 00:24 Warn:  0 ==      ============================================= CALLSTACK : ============================================================== .... <zError.cpp,#474>
    [w] 00:24 Warn:  0 00      23:00731F95 (0x00AB4108 0x00000000 0x00AB40C0 0x00226519) Gothic2.exe, oCNpc::GetSlotItem()+5 byte(s), P:\dev\g2addon\release\Gothic\_ulf\oNpc.cpp, line 2645 .... <zError.cpp,#474>
    [w] 00:24 Warn:  0 00      23:00792568 (0x002262B8 0x00AB4108 0x00000000 0x00AB40C0) Gothic2.exe, zCParser::DoStack()+3080 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1433 .... <zError.cpp,#474>
    [w] 00:24 Warn:  0 00      23:00792504 (0x002264CC 0x00AB4108 0x00000000 0x00AB40C0) Gothic2.exe, zCParser::DoStack()+2980 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1415 .... <zError.cpp,#474>
    [w] 00:24 Warn:  0 00      23:00792504 (0x00226AC1 0x00AB4108 0x00000000 0x00AB40C0) Gothic2.exe, zCParser::DoStack()+2980 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1415 .... <zError.cpp,#474>
    [w] 00:24 Warn:  0 00      23:00792504 (0x00226BC9 0x00AB4108 0x00000000 0x00AB40C0) Gothic2.exe, zCParser::DoStack()+2980 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1415 .... <zError.cpp,#474>
    [w] 00:24 Warn:  0 00      23:00792504 (0x00226BF5 0x00AB4108 0x00000000 0x00AB40C0) Gothic2.exe, zCParser::DoStack()+2980 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1415 .... <zError.cpp,#474>
    [w] 00:24 Warn:  0 00      23:00792504 (0x002466A4 0x00AB4108 0x00000000 0x00AB40C0) Gothic2.exe, zCParser::DoStack()+2980 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1415 .... <zError.cpp,#474>
    [w] 00:24 Warn:  0 00      23:00792504 (0x00246996 0x00AB4108 0x00000000 0x00AB40C0) Gothic2.exe, zCParser::DoStack()+2980 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1415 .... <zError.cpp,#474>
    [w] 00:24 Warn:  0 00      23:00792504 (0x00225A52 0x00AB4108 0x00000000 0x00AB40C0) Gothic2.exe, zCParser::DoStack()+2980 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1415 .... <zError.cpp,#474>
    [w] 00:24 Warn:  0 00      23:00792504 (0x00228B9E 0x2866E9E0 0x00AB4118 0x00AB40C0) Gothic2.exe, zCParser::DoStack()+2980 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1415 .... <zError.cpp,#474>
    [w] 00:24 Warn:  0 00      23:00792504 (0x00230E00 0x0135F7F8 0x00000000 0x0135FC90) Gothic2.exe, zCParser::DoStack()+2980 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1415 .... <zError.cpp,#474>
    [w] 00:24 Warn:  0 00      23:00792CBF (0x00000000 0x0135F7F8 0x00AB40C0 0x1C0F7008) Gothic2.exe, zCParser::CallFunc()+719 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1551 .... <zError.cpp,#474>
    [w] 00:24 Warn:  0 00      23:0042B9E8 (0x00000000 0x00792568 0x1BF9A78C 0x00AB4118) Gothic2.exe, CGameManager::PlayVideo()+168 byte(s), P:\dev\g2addon\release\Gothic\_bert\oGameManager.cpp, line 1969 .... <zError.cpp,#474>
    [w] 00:24 Warn:  0 00      23:0081B6D8 (0x351F6200 0x0135F9C0 0x34E126B0 0xFFFFFFFF) Gothic2.exe, SetFileAttributesA()+228116 byte(s) .... <zError.cpp,#474>
    [w] 00:24 Warn:  0 00      23:0040317B (0x006D45B0 0x008B23B3 0x0082E6F0 0x0C406198) Gothic2.exe, std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Grow()+251 byte(s), P:\vs6\VC98\INCLUDE\xstring, line 569+17 byte(s) .... <zError.cpp,#474>
    [w] 00:24 Warn:  0 00      23:00792CBF (0x0135FA90 0x00800E8B 0x0082E6F0 0x0046F400) Gothic2.exe, zCParser::CallFunc()+719 byte(s), P:\dev\g2addon\release\ZenGin\_ulf\zParser.cpp, line 1551 .... <zError.cpp,#474>
    [w] 00:24 Warn:  0 00      23:66481A56 (0x00000000 0x00000000 0x00000000 0x00000000) SHW32.DLL, shi_malloc()+22 byte(s) .... <zError.cpp,#474>
    [w] 00:24 Warn:  0 ==      ===================================== UNHANDLED EXCEPTION OCCURED ====================================================== .... <zError.cpp,#474>
    [w] 00:31 Warn:  0 B:       GMAN: gameSession is existing. Call CGameManager::Done() before! .... <oGameManager.cpp,#375>
    [i] 00:31 Info:  1 B:       VFILE: Deinitializing filesystem (VDFS) .... <zDisk_Vdfs.cpp,#619>
    [i] 00:31 Info:  2 B:       zDSK: 0 files were simultanously open! .... <zDisk_Vdfs.cpp,#625>
    [i] 00:31 Info:  3 B:       VP: zBinkPlayer deinitialized .... <zBinkPlayer.cpp,#62>
    [i] 00:31 Info:  2 N:       MSB: Loading Model-Script (binary) 'HUMANS.MDS' .... <zModelProto.cpp,#4849>

    Und hier nochmal der aktuellste Code:

    Code:
    func int BetterTorches_GetSlotItem()
    {
        CALL_zStringPtrParam ("ZS_LEFTHAND");
        CALL__thiscall (_@(hero), MEMINT_SwitchG1G2(6878448, 7544720));
        
        return CALL_RetValAsPtr();
    };
    Code:
    func void BetterTorches_GivePlayerTorch()
    {
        MEM_SetShowDebug(true);
        
        if (!Hlp_IsValidNpc(hero))
        {
            printDebug("[BetterTorches] Hero not valid, skip 1 frame!");
            
            return;
        };
        
        printDebug("[BetterTorches] Hero is valid!");
        
        if (GOTHIC_BASE_VERSION != 1)
        {
            var int ptr; ptr = BetterTorches_GetSlotItem();
    
    
            if ((BetterTorches_Torch) && (!ptr))
            {
                BetterTorches_Equip();
                
                if (Npc_HasItems (hero, ItLsTorch) > 0)
                {
                    Npc_RemoveInvItem (hero, ItLsTorch);
                };
            };
        };
    
    
        FF_Remove(BetterTorches_GivePlayerTorch);
    };

    Interessant ist eben auch, dass die BetterTorches_GetSlotItem-Funtkion auch für Gothic 1 verwendet wird und dieses scheinbar im Gegensatz zu Gothic 2 überhaupt keine Probleme damit hat. Dort verwende ich es zwar in einer anderen Funktion, aber ebenfalls genau so, wie hier in der BetterTorches_GivePlayerTorch.


    Edit: Ich habe nun auch nochmal versucht, FF_ApplyOnce per oCGame::CloseLoadscreen-Hook aufzurufen, die Funktion, die zumindest laut Print wohl nur dann aufgerufen wird, wenn ein Spielstand geladen wurde. Das ist aber scheinbar nicht der Fall. Denn obwohl FF_ApplyOne im Hook eingetragen ist und nicht mehr in der Startup direkt steht, wird der Print von Cryp18Struct nach einem Neubeginn in zSpy noch ausgeben. Auch tritt wohl deshalb auch immer noch der Absturz auf.
    Ich bräuchte nun also irgendeine Funktion, die tatsächlich nur aufgerufen wird, wenn irgendein Spielstand geladen, allerdings kein neues Spiel gestartet wurde. Bestenfalls irgendeine, die direkt nach dem laden aufgerufen wird. Ich bin mir zwar relativ sicher, dass es eine solche gibt und habe auch mal die Engine-Funktionen durchsucht, bis auf CloseLoadscreen allerdings selbst keine weitere gefunden. Ich weiß, dass es mit LeGo die Gamestate-Abfragen gibt. Diese können mit Ninja allerdings leider nicht verwendet werden. Natürlich kann ich auch nicht mit Sicherheit sagen, dass die AV nicht mehr auftritt, wenn die Funktion bei einem kompletten Neubeginn einfach ignoriert wird, momentan sieht es ja aber zumindest so aus, als würde das Problem immer nur dann auftreten, wenn eben zwei Mal in einer Sitzung ein neues Spiel begonnen bzw. auch wenn erst ein Spielstand geladen und danach ein neues Spiel gestartet wird.

    Der momentane Code mit dem Hook:

    Code:
    func void BetterTorches_Hook_CloseLoadscreen_G2(){
    	FF_ApplyOnce(BetterTorches_GivePlayerTorch);
    	
    	Print ("TEST!!");
    };
    
    
    
    
    // Hier alle einzelnen Hooks eintragen!
    func void BetterTorches_AllHooks()
    {
    	BetterTorches_oCGamePause_Init();
    	BetterTorches_oCGameCloseLoadscreen_Init();
    };

    Init_Global:

    Code:
    BetterTorches_AllHooks();
    Geändert von Bloodfly91 (28.10.2019 um 17:42 Uhr)

  13. Beiträge anzeigen #13 Zitieren
    Ehrengarde Avatar von mud-freak
    Registriert seit
    Dec 2005
    Beiträge
    2.199
     
    mud-freak ist offline
    Deine Ideen “im Edit” hören sich sehr abenteuerlich an. Es sollte eigentlich alles problemlos über die Init_Global funktionieren. Für mich war es etwas schwierig zu folgen: Bestehen nun nur noch Probleme wenn du deine Skripte als Patch erstellst?[1] Wenn ja, will ich nicht abstreiten, dass das tatsächlich einfach mit Ninja zusammenhängen könnte. Ich bin gerade unterwegs, kann mir das gern mal nächste Woche anschauen. Wenn du nichts dagegen hast, kannst du mir den gesamten Patch (als fertige VDF) mal zukommen lassen (PN).

    [1] Freut mich sehr, dass du der Dokumentation folgst und deine Funktionen/Variablen deinem Patch entsprechend benennst. In deinen Code-Auszügen initialisierst du LeGo mit LeGo_Init. Du benutzt aber für den Patch schon LeGo_MergeFlags, oder?



    PS: Anstatt Ninja-Patch, nennt es lieber einfach Patch. Die Bezeichnung war in der Vergangenheit für einige Spieler erstaunlich verwirrend. Jetzt, wo Ninja nicht mehr in einem solchen Patch enthalten ist, ist es einfach nur noch ein normaler Patch, der Ninja voraussetzt.
    Geändert von mud-freak (29.10.2019 um 08:59 Uhr)

  14. Homepage besuchen Beiträge anzeigen #14 Zitieren
    Team Velen
    Registriert seit
    Aug 2015
    Beiträge
    952
     
    Bloodfly91 ist offline
    Zitat Zitat von mud-freak Beitrag anzeigen
    Deine Ideen “im Edit” hören sich sehr abenteuerlich an. Es sollte eigentlich alles problemlos über die Init_Global funktionieren. Für mich war es etwas schwierig zu folgen: Bestehen nun nur noch Probleme wenn du deine Skripte als Patch erstellst?[1] Wenn ja, will ich nicht abstreiten, dass das tatsächlich einfach mit Ninja zusammenhängen könnte. Ich bin gerade unterwegs, kann mir das gern mal nächste Woche anschauen. Wenn du nichts dagegen hast, kannst du mir den gesamten Patch (als fertige VDF) mal zukommen lassen (PN).

    [1] Freut mich sehr, dass du der Dokumentation folgst und deine Funktionen/Variablen deinem Patch entsprechend benennst. In deinen Code-Auszügen initialisierst du LeGo mit LeGo_Init. Du benutzt aber für den Patch schon LeGo_MergeFlags, oder?



    PS: Anstatt Ninja-Patch, nennt es lieber einfach Patch. Die Bezeichnung war in der Vergangenheit für einige Spieler erstaunlich verwirrend. Jetzt, wo Ninja nicht mehr in einem solchen Patch enthalten ist, ist es einfach nur noch ein normaler Patch, der Ninja voraussetzt.
    Ja, so ist es. Ich habe es soeben auch nochmal als normales Skript mit den aktuellsten Änderungen mit einer Gothic 2 Modding-Installation getestet und konnte überhaupt keine Probleme feststellen. Die treten dann tatsächlich erst auf, wenn das Skript als Patch mit dem Gothic 2 Originalspiel oder Gothic 2 und Mods verwendet wird. Gothic 1 hat damit scheinbar überhaupt keine Probleme, jedoch werden zwei der Funktionen vom Skript für Gothic 1 auch nicht verwendet.
    Für den Patch benutze ich LeGo_MergeFlags.
    Nein, dagegen habe ich überhaupt nichts. Es wäre super, wenn du dir das mal anschauen könntest, danke!

  15. Beiträge anzeigen #15 Zitieren
    Ehrengarde Avatar von mud-freak
    Registriert seit
    Dec 2005
    Beiträge
    2.199
     
    mud-freak ist offline
    Ich habe es mir mal anschaut.

    Die Annahme es liege an BetterTorches_GivePlayerTorch, ausgehend von der Init_Global war etwas zu voreingenommen. Die Funktion in der die Access Violation auftritt, wird auch von anderen Stellen aufgerufen.
    Die Abfrage zum gültigen Hero ist also auch in der Funktion selbst nötig:
    Code:
    func int BetterTorches_GetSlotItem()
    {
        if (!Hlp_IsValidNpc(hero)) {
            return 0;
        };
    
        // ...
    Das Problem ist dein Hook: BetterTorches_Hook_oCGamePause_G2
    Dass der Absturz nur mit dem Patch auftrat kann am aktivierten Dev-Modus liegen.

    Anstatt das Pause-Menu zu hooken, um die Variable BetterTorches_Torch ("Fackel in Benutzung") zu setzen kannst du vielleicht direkt das Speichern des Spiels hooken (damit erwischst du auch das Quicksave):
    Code:
    if (GOTHIC_BASE_VERSION == 2) {
        HookEngineF(oCSavegameManager__SetAndWriteSavegame, 5, BetterTorches_SetPlayerVarTorch);
    };
    oCSavegameManager__SetAndWriteSavegame ist bereits durch LeGo definiert. Die Abfrage von G1 oder G2 kannst du dir dann in BetterTorches_SetPlayerVarTorch sparen, wenn du den Hook, wie oben, nur für G2 registrierst. (Ebenso mit BetterTorches_GivePlayerTorch - die braucht für G1 gar nicht erst aufgerufen zu werden).


    Noch vier Bemerkungen:

    1. Es ist leserlicher, wenn du die Adressen als Konstanten mit sinnvollen Namen definierst, z.B.
    Code:
    FUNC VOID BetterTorches_Equip()
    {
        CreateInvItem (hero, ItLsTorchBurning);
    
        const int oCNpc__Equip_G1 = 6908144; //0x6968F0
        const int oCNpc__Equip_G2 = 7576720; //0x739C90
    
        CALL_PtrParam (_@(ItLsTorchBurning));
        CALL__thiscall (_@(hero), MEMINT_SwitchG1G2(oCNpc__Equip_G1, oCNpc__Equip_G2));
    };

    2. Wenn nicht zwingend notwendig, verzichte in einem Patch lieber auf PrintS und nimm das normale Print. Je weniger Abhängigkeiten von PermMem in einem Patch desto besser.

    3. Füge getreu der Namenskonvention noch den Prefix "Ninja_" zu all deinen Symbolen hinzu (z.B. Ninja_BetterTorches_Torch und Ninja_BetterTorches_GetSlotItem, usw...). Dadurch ist dann wirklich ausgeschlossen, dass der Patch versehentlich Symbole einer Mod überschreibt.

    4. Wenn du deinen Patch noch multi-lingual gestalten willst, kannst du die Strings in den Print-Ausgaben auf dem Bildschirm noch entsprechend der Lokalisierung anpassen.

  16. Homepage besuchen Beiträge anzeigen #16 Zitieren
    Team Velen
    Registriert seit
    Aug 2015
    Beiträge
    952
     
    Bloodfly91 ist offline
    Vielen Dank, mud-freak. Ich konnte mit diesen Änderungen bisher keinen Absturz mehr feststellen.

    Ein Problem gibt es leider noch, nämlich mit "oCSavegameManager__SetAndWriteSavegame". Die wird zu spät aufgerufen, die Variable also zu spät gesetzt und nicht mehr ins Savegame geschrieben. Das wurde mir dadurch bestätigt, dass der Spieler nach dem Laden eines Spielstandes plötzlich wieder keine Fackel mehr trug und auch durch von mir eingebaute Prints. Deshalb auch der Hook, sobald das Spiel pausiert wird, was soweit tadellos funktionierte. Nur für Quicksave eben nicht. Ich bräuchte also irgendeine Möglichkeit, die Variable tatsächlich erst kurz vor dem Speichern auf 'true' zu setzen.

  17. Beiträge anzeigen #17 Zitieren
    Ehrengarde Avatar von mud-freak
    Registriert seit
    Dec 2005
    Beiträge
    2.199
     
    mud-freak ist offline
    Ah ok. Nimm mal diesen Hook. Die Funktion wird aufgerufen, bei (vor) jedem Speichern - d.h. auch beim Weltenwechsel. Das ist für deine Zwecke sicher auch sinnvoll.

    Code:
    if (GOTHIC_BASE_VERSION == 2) {
        const int oCGame__WriteSavegame = 7098960; //0x6C5250
        HookEngineF(oCGame__WriteSavegame, 6, BetterTorches_SetPlayerVarTorch);
    };

  18. Homepage besuchen Beiträge anzeigen #18 Zitieren
    Team Velen
    Registriert seit
    Aug 2015
    Beiträge
    952
     
    Bloodfly91 ist offline
    Zitat Zitat von mud-freak Beitrag anzeigen
    Ah ok. Nimm mal diesen Hook. Die Funktion wird aufgerufen, bei (vor) jedem Speichern - d.h. auch beim Weltenwechsel. Das ist für deine Zwecke sicher auch sinnvoll.

    Code:
    if (GOTHIC_BASE_VERSION == 2) {
        const int oCGame__WriteSavegame = 7098960; //0x6C5250
        HookEngineF(oCGame__WriteSavegame, 6, BetterTorches_SetPlayerVarTorch);
    };
    Sorry für die späte Rückmeldung, mit dieser Funktion funktioniert es nun einwandfrei!

    Nun bräuchte ich noch irgendeine bestenfalls einfache Möglichkeit, eine Taste zum ausrüsten bzw. wegstecken einer Fackel in der Gothic-Ini festzulegen, die ich per Skript dann auch auslesen kann. Ausschließlich die T-Taste hierfür festzulegen, könnte wohl problematisch werden, sollte der Patch mit irgendeiner Modifikation verwendet werden, die diese Taste bereits für irgendetwas verwendet oder falls der Spieler irgendeine Option von Gothic auf diese Taste gelegt hat. Hat jemand 'ne Idee, wie man das umsetzen könnte?

  19. Beiträge anzeigen #19 Zitieren
    Ehrengarde Avatar von mud-freak
    Registriert seit
    Dec 2005
    Beiträge
    2.199
     
    mud-freak ist offline
    Zitat Zitat von Bloodfly91 Beitrag anzeigen
    Sorry für die späte Rückmeldung, mit dieser Funktion funktioniert es nun einwandfrei!
    Sehr schön zu hören!


    Zitat Zitat von Bloodfly91 Beitrag anzeigen
    Nun bräuchte ich noch irgendeine bestenfalls einfache Möglichkeit, eine Taste zum ausrüsten bzw. wegstecken einer Fackel in der Gothic-Ini festzulegen, die ich per Skript dann auch auslesen kann. Ausschließlich die T-Taste hierfür festzulegen, könnte wohl problematisch werden, sollte der Patch mit irgendeiner Modifikation verwendet werden, die diese Taste bereits für irgendetwas verwendet oder falls der Spieler irgendeine Option von Gothic auf diese Taste gelegt hat. Hat jemand 'ne Idee, wie man das umsetzen könnte?
    Drei Dinge sind zu beachten:
    1. Wenn ich mich recht erinnere, reichen folgende Abfragen (jede Aktion ist über zwei Tasten zugänglich; erst- (primär) und zweit (sekundär) Tastenbelegung).
      Code:
      MEM_GetKey("meinKnopf")
      MEM_GetSecondaryKey("meinKnopf")
      zum Beispiel
      Code:
      if (MEM_KeyState(MEM_GetKey("meinKnopf")) == KEY_PRESSED)
      || (MEM_KeyState(MEM_GetSecondaryKey("meinKnopf")) == KEY_PRESSED) {
         // Do something
      };


    2. Diese funktionieren nur, wenn "meinKnopf" in der Gothic.ini in der Sektion "KEYS" schon definiert ist. Das kannst du sicherstellen, in dem du diesen Eintrag beim Start des Spiels erstellst, wenn er noch nicht existiert (hier beispielhhaft definiert mit der Taste T und der Komma-Taste als erst- und zweit Tastenbelegung):
      Code:
      if (!MEM_GothOptExists("KEYS", "meinKnopf")) {
          MEM_SetKeys("meinKnopf", KEY_T, KEY_COMMA);
      };
      In einem Patch ist es sinnvoll, diesen Code in die Menü-Initialisierung zu schreiben, damit diese Tasten schon vorm Hauptmenü in der ini gesetzt sind:
      Code:
      /*
       * Menu initialization function called by Ninja every time a menu is opened
       */
      func void Ninja_[PatchName]_Menu(var int menuPtr) {
          MEM_InitAll();
      
          const int setKeysOnce = 0;
          if (!setKeysOnce) {
              if (!MEM_GothOptExists("KEYS", "meinKnopf")) {
                  MEM_SetKeys("meinKnopf", KEY_T, KEY_COMMA);
              };
              setKeysOnce = 1;
          };
      };


    3. In der Ini-Datei sind diese Tasten in hexadezimal gespeichert und ganz und gar nicht zugänglich zum manuellen Bearbeiten. Daher ist es sinnvoll, die Tastenbelegung ins Spielmenü aufzunehmen.

      Neue Menü-Einträge mittels Patch hinzuzufügen ist hier etwas erklärt. Die Erklärung ist aber sehr generell und nicht speziell für das Tastenbelegungsmenü. Sag Bescheid, wenn du dabei Hilfe brauchst.

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