Potenzieller Bug: Wenn ich nach dem "manuellen" (Bar_Hide(.)) Ausblenden der Bar das Spielmenü, Tagebuch, oder Statusbildschirm öffne und wieder schließe, dann ist die Bar wieder da. Hier scheint es eventuell einen Bug zu geben im Code, der die Bar im Menü ausblenden soll, wodurch nach Ende des Menüs auch bars wieder angezeigt werden, die vorher ausgeblendet waren. Ich nehme an, dass dieser Bug auch zur Anzeige der Bars führt, wenn ein neues Spiel gestartet oder ein Spielstand geladen wird.
Hier ein minimal-getesteter Versuch, das Problem zu beheben:
Angepasste Klasse _bar (damit es mitgespeichert wird, da insbesondere zum Speichern ja das Menü geöffnet und daher die Bars ausgeblendet werden)
Code:
class _bar {
var int valMax;
var int barW;
var int v0; // zCView(h)
var int v1; // zCView(h)
var int autoHide;
};
Neue Funktionen Bar_Hide_Auto und Bar_Show_Auto (merken sich / überprüfen ob eine Bar vom AutoHide-Sys:
Code:
func void Bar_Hide_Auto(var int bar)
{
if(!Hlp_IsValidHandle(bar)) { return; };
var _bar b; b = get(bar);
var zCView v; v = View_Get(b.v0);
b.autoHide = v.isOpen;
Bar_Hide(bar);
};
func void Bar_Show_Auto(var int bar)
{
if(!Hlp_IsValidHandle(bar)) { return; };
var _bar b; b = get(bar);
if (b.autoHide) {
b.autoHide = FALSE;
Bar_Show(bar);
};
};
Angepasste Funktion _Bar_Update (im Hook die _Auto Funktionen aufrufen):
Code:
func void _Bar_Update() {
var int status; status = _Bar_PlayerStatus();
const int SET = 0;
if (SET != status) {
SET = status;
if (SET) {
foreachHndl(_bar@, Bar_Show_Auto);
} else {
foreachHndl(_bar@, Bar_Hide_Auto);
};
};
};
Mögliche Probleme, die mir spontan einfallen:
1) Speichern / Laden -- hat die Erweiterung der _bar Klasse die gewünschte Wirkung?
2) Ist die Klasse _bar oder die Klasse Bar besser geeignet? Oder lieber eine eigene Tabelle / Liste, die separat ist?
3) Kann während man im Menü ist anderer Code versuchen, eine Bar anzuzeigen / zu verstecken? In diesem Fall könnte man z.B. in Bar_Show und Bar_Hide ggf. den .autoHide Status überschreiben (darf dann aber diese beiden Funktionen wohl nicht aus den _Auto Funktionen heraus aufrufen.
4) reicht v0.isOpen aus oder gibt es da einen verlässlicheren Test, den man verwenden sollte? (vielleicht allgemein eine Funktion Bar_IsOpen und / oder View_IsOpen einfügen?)
Mit diesen Punkten kennen sich aber andere hier vermutlich deutlich besser aus als ich, daher warte ich mal ab, bevor ich da mehr Arbeit rein stecke.
--
Davon unabhängig: Sollte das Verstecken der Bars vielleicht optional sein für den Modder, z.B. per LeGo Initialisierung? Ich weiß nicht, ob unter manchen Bedingungen Modder vielleicht gerne die Bars angezeigt haben möchten. Oder gleich optional pro Bar einstellbar, ob sie ausgeblendet werden soll oder nicht.
Vor einer weiteren Eigenschaft der _bar-Klasse hatte ich mich beim Implementieren des automatischen Verbergens etwas gesträubt wegen Rückwärtskompatibilitäten. Wenn wir aber explizit einen (Un-)Archiver schreiben, der darauf Rücksicht nimmt, ob diese Eigenschaft im Save existiert, ist das kein großes Problem.
Ich würde die Eigenschaft allerdings hidden nennen, die davon abhält einen manuell versteckten Balken beim Schließen von Menüs sichtbar zu machen. autohide ist evtl. etwas irreführend. Die Mechanik des automatischen Verbergens würde ich gern so beibehalten und nicht dem Modder überlassen (wie du am Ende des letzten Posts vorschlägst). Schließlich handelt es sich Balken, dem Prinzip der existierenden Standardbalken folgend. Wer Balken auch während eines Menüs o.Ä. anzeigen will, der erstellt meiner Meinung nach keine Balken, sondern etwas anderes und kann sich manuell an Views bedienen.
Ich werde das manuelle Verstecken in LeGo-Bars, ähnlich deiner Vorschläge, heute Nachmittag korrigieren.
Ich habe das manuelle Verstecken von LeGo-Bars nun korrigiert. Die Änderung sollte dann in der nächsten Version von LeGo erhalten sein. Wer möchte, kann bis dahin schon die Datei Bars.d mit der aktualisierten hier ersetzen.
Nach außen hin (für den Modder) ändert sich dadurch nichts an der Handhabung. Lediglich bleiben Balken, die mit Bar_Hide vom Skripter verborgen werden auch nach Öffnen und Schließen von Menüs und über Speichern und Laden hinweg versteckt. Ansonsten ist die Mechanik unverändert. Rückwärtkompatibilität ist gewährleistet, sodass die Änderung problemlos mit alten Speicherständen zurecht kommt.
Zitat von F a w k e s
Would it be possible to add into Cursor.d support for more events
Sorry for the late reaction. I think double clicks are quite rare in video games and as you state yourself, the implementation is a bit tricky - especially with regard to differentiating between normal and double click. I have no good idea how to implement this cleanly and intuitively, without adding to much complexity to the LeGo-Cursor package.
For now, if you rely on it on your mod, I would suggest not to modify "internal" code of LeGo, but to rather implementing it within a custom cursor listener[1]. This is much easier to maintain and keeps the LeGo scripts intact to not collide with future LeGo updates and patches (script patches will overwrite LeGo scripts to the latest development versions to ensure proper functionality).
[1] Add a listener and check if a left click event was received less than x ms after another one.
Code:
Event_Add(Cursor_Event, MyCursorListener);
// ...
func void MyCursorListener(var int state){
const int delay = 300;
var int prevLeftClick;
var int timer; timer = Timer();
if (state == CUR_LeftClick){
if (prevLeftClick + delay < timer){
PrintS("Doubleclick!");
} else {
PrintS("Leftclick!");
};
prevLeftClick = timer;
};
};
Ich habe das manuelle Verstecken von LeGo-Bars nun korrigiert. Die Änderung sollte dann in der nächsten Version von LeGo erhalten sein. Wer möchte, kann bis dahin schon die Datei Bars.d mit der aktualisierten hier ersetzen.
Nach außen hin (für den Modder) ändert sich dadurch nichts an der Handhabung. Lediglich bleiben Balken, die mit Bar_Hide vom Skripter verborgen werden auch nach Öffnen und Schließen von Menüs und über Speichern und Laden hinweg versteckt. Ansonsten ist die Mechanik unverändert. Rückwärtkompatibilität ist gewährleistet, sodass die Änderung problemlos mit alten Speicherständen zurecht kommt.
Danke für das schnelle Einbauen (und gute Idee, sich das manuelle Verstecken zu merken statt des Auto-Versteckens)
Bei der Entwicklung eines Patches (hier speziell Quickloot) habe ich eine Option eingebaut Text per Animation an den Bildschirmrand zu bevördern.
Nun hat ein Spieler festgestellt, das der Patch (speziell, nur die Animation) mit LoA nicht funktioniert.
der zSpy wirft für jede erzeugte Animation den folgenden Stacktrace:
Spoiler:(zum lesen bitte Text markieren)
Code:
01:27 Warn: 0 C: SCRIPT: Npc_IsInState(): illegal param: "LOA_GAR_60033_CORTEZWU" is NULL. .... <oGameExternal.cpp,#252>
01:27 Warn: 0 C: SCRIPT: last parser func-name: _HOOK .... <oGameExternal.cpp,#262>
01:28 Info: 2 U: NPC: AI:Removed NPC Cortez / LOA_MIL_6207_CORTEZ .... <oNpc.cpp,#9082>
01:28 Warn: 0 Q: Assigning new handle 46 (ZCVIEWTEXTPRINT) to patch 'QUICKLOOT'.
01:28 Info: 5 U: FNT: Loading Font: Ninja_QuickLoot_Font_DE.tga .... <zFonts.cpp,#196>
01:28 Info: 4 B: FONT: Loading Font-Data: \_WORK\DATA\TEXTURES\_COMPILED\NINJA_QUICKLOOT_FONT_DE.FNT .... <zFonts.cpp,#361>
01:28 Warn: 0 Q: Assigning new handle 47 (A8HEAD@) to patch 'QUICKLOOT'.
01:28 Warn: 0 Q: Assigning new handle 48 (A8HEAD@) to patch 'QUICKLOOT'.
01:28 Warn: 0 Q: Assigning new handle 49 (A8COMMAND@) to patch 'QUICKLOOT'.
01:28 Warn: 0 Q: Assigning new handle 50 (A8COMMAND@) to patch 'QUICKLOOT'.
01:28 Warn: 0 Q: Assigning new handle 51 (A8COMMAND@) to patch 'QUICKLOOT'.
01:28 Fault: 0 Q: [start of stacktrace]
01:28 Fault: 0 Q: MEMINT_HANDLEERROR(2, 'A8 sucks. Handle 47 of instance A8HEAD@ messed up with a queue of -1981943312. I will ignore it.
The pointer was 59696992...') + 62 bytes
01:28 Fault: 0 Q: MEM_WARN('A8 sucks. Handle 47 of instance A8HEAD@ messed up with a queue of -1981943312. I will ignore it.
The pointer was 59696992...') + 21 bytes
01:28 Fault: 0 Q: _ANIM8_LOOP(47) + 221 bytes
01:28 Fault: 0 Q: FOREACHHNDL(9139, _ANIM8_LOOP) + 273 bytes
01:28 Fault: 0 Q: [UNKNOWN] +44936901 bytes
01:28 Fault: 0 Q: _ANIM8_FFLOOP() + 15 bytes
01:28 Fault: 0 Q: FRAMEFUNCTIONS(4) + 157 bytes
01:28 Fault: 0 Q: FOREACHHNDL(9139, _ANIM8_LOOP) + 273 bytes
01:28 Fault: 0 Q: [UNKNOWN] +44936901 bytes
01:28 Fault: 0 Q: _FF_HOOK() + 32 bytes
01:28 Fault: 0 Q: MEM_CALLBYID(151782) + 224 bytes
01:28 Fault: 0 Q: _HOOK(2031966920, 582020096, 0, 20315280, 20315148, 0, 8635020, 582020096, 2013433864) + 468 bytes
01:28 Fault: 0 Q: [UNKNOWN] +1006854061 bytes
01:28 Fault: 0 Q: [end of stacktrace]
Liegt das Problem an Mir, Ninja, LeGo oder LoA? (Das Problem tritt in anderen Modifikationen nicht auf und auch in LoA scheint es zwar sehr oft, aber nicht immer aufzutreten.
Die Stelle in LeGo die für den Stacktrace verantwortlich ist
Spoiler:(zum lesen bitte Text markieren)
Code:
func int _Anim8_Loop(var int hndl) {
var A8Head h; h = get(hndl);
if(!h.queue) {
return rContinue;
};
// HIER IST h.queue negativ.
if(h.queue < 1048576) {
var int s; s = SB_New();
SB ("A8 sucks. Handle ");
SBi(hndl);
SB (" of instance ");
SB (_PM_InstName(getInst(hndl)));
SB (" messed up with a queue of ");
SBi(h.queue);
SB (". I will ignore it.");
SB (STR_Unescape("\n"));
SB ("The pointer was ");
SBi(getPtr(hndl));
SB ("...");
MEM_Warn(SB_ToString());
SB_Destroy();
return rContinue;
};
// ...
return rContinue;
};
Spielst du LoA mit dem LAA/4GiB-Patch? Ich glaube das ist mal wieder ein Fall von übermütigen Sanity-Checks, die da überprüfen, dass der Pointer nicht negativ wird - was bei aktiviertem LAA-Flag aber vorkommt.
Edit: Ich sehe gerade du hast den Fehler mit dem SystemPack produziert, da dürfte der LAA-Patch enthalten sein. Ich glaube du kannst den von dir markierten Block einfach löschen, das ist kein sinnvoller Check. Magst du das ausprobieren, da du ja gerade ein Setup zum Testen hast?
Ich hatte zum Test einfach mal ein "h.queue >= 0 && " zur Bedingung angefügt. (Keine Ahnung warum da so genau auf "< 1048576" geprüft wurde)
Damit haben die Animationen funktioniert.
Wenn das "< 1048576" keine Bedeutung hat, kann der Codeblock bestimmt weg.
ist das etwas, was jeder bei seiner LeGo-Version anpassen sollte, um Probleme zu vermeiden?
tl;dr: Ja sollte jeder anpassen. ABER nur wenn die Funktionalität sichergestellt ist. (Einfach auf ein Ikarus/LeGo update warten und die Mod-Skripte aktualisieren)
Langer Text:
Generell sind Ikarus & LeGo ja nur Bibliotheken für Funktionalität welche man immer wieder aktualisieren kann/sollte.
Der Vorteil solcher Bibliotheken ist, das sie Funktionalität stellen und Komplexität abstrahieren (verstecken)
Wenn im nachhinein Probleme festgestellt werden, wie zur heutigen Zeit, wo mehr Spieler mit dem "LargeAddressAware"-Flag spielen. (LAA-Hack, 4GB Patch, wie auch immer man es nennen mag)
Dann können viele dieser Probleme schnell und zentral behoben werden ohne das die Funktionalität darunter leidet.
Wenn jetzt, durch wen auch immer, sichergestellt wird, dass diese Abfrage "nutzlos" ist, wird das in LeGo übernommen und es gibt eine aktualisierte Version.
Mod Hersteller sollten generell schauen, das sie zumindest vor dem Release ihrer Mod, gerade wenn diese schon Jahre in der Entwicklung ist,
prüfen ob für ihre Abhängigkeiten Aktualisierungen vorhanden sind und Evaluieren ob diese Änderungen für sie relevant sind und dann ggf. die Skripte aktualisieren.
In diesem Fall gab es in den letzten paar LeGo Versionen (und womöglich in der nächsten) Fehler-Behebungen welche
speziell für Spieler von großen Modifikationen, "HD" Texturen und dem GD3D11 Renderer sehr wichtig sind. -> mehrere 4GB Patch "Probleme" behoben.
tl;dr: Ja sollte jeder anpassen. ABER nur wenn die Funktionalität sichergestellt ist. (Einfach auf ein Ikarus/LeGo update warten und die Mod-Skripte aktualisieren)
Langer Text:
Generell sind Ikarus & LeGo ja nur Bibliotheken für Funktionalität welche man immer wieder aktualisieren kann/sollte.
Der Vorteil solcher Bibliotheken ist, das sie Funktionalität stellen und Komplexität abstrahieren (verstecken)
Wenn im nachhinein Probleme festgestellt werden, wie zur heutigen Zeit, wo mehr Spieler mit dem "LargeAddressAware"-Flag spielen. (LAA-Hack, 4GB Patch, wie auch immer man es nennen mag)
Dann können viele dieser Probleme schnell und zentral behoben werden ohne das die Funktionalität darunter leidet.
Wenn jetzt, durch wen auch immer, sichergestellt wird, dass diese Abfrage "nutzlos" ist, wird das in LeGo übernommen und es gibt eine aktualisierte Version.
Mod Hersteller sollten generell schauen, das sie zumindest vor dem Release ihrer Mod, gerade wenn diese schon Jahre in der Entwicklung ist,
prüfen ob für ihre Abhängigkeiten Aktualisierungen vorhanden sind und Evaluieren ob diese Änderungen für sie relevant sind und dann ggf. die Skripte aktualisieren.
In diesem Fall gab es in den letzten paar LeGo Versionen (und womöglich in der nächsten) Fehler-Behebungen welche
speziell für Spieler von großen Modifikationen, "HD" Texturen und dem GD3D11 Renderer sehr wichtig sind. -> mehrere 4GB Patch "Probleme" behoben.
Ja, genau deshalb frage ich hier, ob eine Änderung an dieser Stelle ein eindeutiges "Ja, sollte man so machen" ist. Unser nächster Release soll in naher Zukunft kommen und ich würde ich dann den Block
Code:
if(h.queue < 1048576) {
var int s; s = SB_New();
SB ("A8 sucks. Handle ");
SBi(hndl);
SB (" of instance ");
SB (_PM_InstName(getInst(hndl)));
SB (" messed up with a queue of ");
SBi(h.queue);
SB (". I will ignore it.");
SB (STR_Unescape("\n"));
SB ("The pointer was ");
SBi(getPtr(hndl));
SB ("...");
MEM_Warn(SB_ToString());
SB_Destroy();
return rContinue;
};
rauslöschen. Richtig so? Oder ist die Variante mit
Code:
if(h.queue >= 0 && h.queue < 1048576)
besser?
Oder ist irgendein negativer Bereich (z.B. -1048576 bis 0) auch problematisch?
Ich persönlich verstehe nicht, woher 1048576 im "Original" kommt und ob das wichtig ist.
...
Ich persönlich verstehe nicht, woher 1048576 im "Original" kommt und ob das wichtig ist.
Das gleiche ist auch mein Problem, weshalb ich erstmal auf @Lehona, oder irgendjemanden der sich besser mit LeGo auskennt warte bis ich da definitiv was frickel
"theoretisch" würde es reichen den block zu löschen.
Ein Pointer kann überall liegen, außer bei 0 (die Abfrage ist darüber bereits getätigt durch if (!h.queue) {...} ).
Ich kann mir nicht erklären woher 1048576 kommen soll
Dieser Check wurde in Revision 20 von LeGo eingebaut. Ich schätze, das war eine Art Schadensbegrenzung zu der vorherigen Implementierung vom Erstellen der Liste in A8Head.queue und dem nicht-auf-Null-setzen nach Freigabe des Speichers beim Löschen. Die Zahl 1048576 (0x100000) entsprach wahrscheinlich der maximalen Größe der abgebildeten Exe im virtuellen Speicher, um die Gültigkeit des Pointers weiter einzugrenzen. Das ist zwar nur Spekulation, aber da die Liste nun auf anderem Wege erstellt wird und in A8Head-Objekten üblicherweise nicht manuell herumgepfuscht wird, denke ich auch, dass der Block obsolet ist.
Vielleicht weiß Lehona mehr zur "Geschichte" dieser Code-Zeilen. Ansonsten lösche ich die gern aus dem LeGo Repo.
Dieser Check wurde in Revision 20 von LeGo eingebaut. Ich schätze, das war eine Art Schadensbegrenzung zu der vorherigen Implementierung vom Erstellen der Liste in A8Head.queue und dem nicht-auf-Null-setzen nach Freigabe des Speichers beim Löschen. Die Zahl 1048576 (0x100000) entsprach wahrscheinlich der maximalen Größe der abgebildeten Exe im virtuellen Speicher, um die Gültigkeit des Pointers weiter einzugrenzen. Das ist zwar nur Spekulation, aber da die Liste nun auf anderem Wege erstellt wird und in A8Head-Objekten üblicherweise nicht manuell herumgepfuscht wird, denke ich auch, dass der Block obsolet ist.
Vielleicht weiß Lehona mehr zur "Geschichte" dieser Code-Zeilen. Ansonsten lösche ich die gern aus dem LeGo Repo.
Einem Nutzer eines meiner Patches (auf Ninja Basis) ist aufgefallen das die Animationen nur sporadisch funktionierten.
Für jetzt behelfe ich mir indem ich in dem Patch die alte mittels HookDaedalusF(...) die "_Loop_Anim8" überschreibe (mit genau diesem Block rausgeschnitten)
Wäre also echt schön wenn vielleicht in den nächsten 30 Tagen ein Update von LeGo + Ninja verfügbar wäre.
Hallo ich nutze die neuste LeGo Version und habe ein Problem mit den Framefunctions, es wirft mir in regelmäßigen Abständen eine AV. Meistens wenn ich das Inventar öffne/Monster loote. Es ist eigentlich ganz ein einfaches Skript, welches jede Sekunde aufgerufen wird und prüft ob es regnet. Wenn ja dann soll der Held einen Kommentar abgeben. Es funktioniert auch, aber es scheint der Grund für random crashes zu sein. Eventuell hat jemand von euch eine Idee was hier das Problem sein könnte. Danke schon mal.
In der INIT_Global() in der Startup rufe ich folgendes auf:
Code:
FF_ApplyOnceExt(Backgroundtasks, 1000, -1);
Der Code schaut wie folgt aus.
Code:
var int rand;
var string str;
func void Backgroundtasks()
{
// Regen Kommentare
if (LastRainCommentDay != Wld_GetDay())
{
if (Wld_IsRaining())
{
rand = r_MinMax(1, 4);
str = "$Regen";
str = ConcatStrings (str, IntToString(rand));
B_Say(hero, hero, str);
LastRainCommentDay = Wld_GetDay();
};
};
};
Hallo ich nutze die neuste LeGo Version und habe ein Problem mit den Framefunctions, es wirft mir in regelmäßigen Abständen eine AV. Meistens wenn ich das Inventar öffne/Monster loote. Es ist eigentlich ganz ein einfaches Skript, welches jede Sekunde aufgerufen wird und prüft ob es regnet. Wenn ja dann soll der Held einen Kommentar abgeben. Es funktioniert auch, aber es scheint der Grund für random crashes zu sein. Eventuell hat jemand von euch eine Idee was hier das Problem sein könnte. Danke schon mal.
In der INIT_Global() in der Startup rufe ich folgendes auf:
Code:
FF_ApplyOnceExt(Backgroundtasks, 1000, -1);
Der Code schaut wie folgt aus.
...
Also ich würde hierfür eher eine FF_ApplyOnceExtGT benutzen, diese läuft nur wenn das Spiel läuft und man nicht in einem Menü o.ä ist.
Damit sind viele probleme oft schon aus der Welt geschaffen
Mir ist gerade ein Bug in der Trialoge.d aufgefallen. Dieser sorgt dafür, dass alle Npcs, die mal in einem Trialog verstrickt waren, sehr verkorkste Rüstungswerte haben. Da bei mir einige Npcs plötzlich mit negativen Rüstungswerten herumgelaufen sind, waren diese immun gegen so ziemlich alles.
In der _TRIA_Copy sollte deshalb vermutlich noch diese Zeile hinzugefügt werden:
Kann natürlich sein, dass wir an anderer Stelle etwas geändert haben, was diese Zeile erst notwendig macht. Wäre also super, wenn das nochmal jemand validieren könnte =)
Mir ist gerade ein Bug in der Trialoge.d aufgefallen. Dieser sorgt dafür, dass alle Npcs, die mal in einem Trialog verstrickt waren, sehr verkorkste Rüstungswerte haben. Da bei mir einige Npcs plötzlich mit negativen Rüstungswerten herumgelaufen sind, waren diese immun gegen so ziemlich alles.
In der _TRIA_Copy sollte deshalb vermutlich noch diese Zeile hinzugefügt werden:
Kann natürlich sein, dass wir an anderer Stelle etwas geändert haben, was diese Zeile erst notwendig macht. Wäre also super, wenn das nochmal jemand validieren könnte =)
Danke für den Hinweis! Ich konnte das nachstellen und habe es wie von dir vorgeschlagen hier aufgenommen. Ich habe dich vergessen zu erwähnen. Du wirst dann in den Releasenotes der nächsten Version vermerkt. (Hoffentlich vergessen wir das nicht!)
Hallo ich nutze die neuste LeGo Version und habe ein Problem mit den Framefunctions, es wirft mir in regelmäßigen Abständen eine AV. Meistens wenn ich das Inventar öffne/Monster loote. Es ist eigentlich ganz ein einfaches Skript, welches jede Sekunde aufgerufen wird und prüft ob es regnet. Wenn ja dann soll der Held einen Kommentar abgeben. Es funktioniert auch, aber es scheint der Grund für random crashes zu sein. Eventuell hat jemand von euch eine Idee was hier das Problem sein könnte. Danke schon mal.
In der INIT_Global() in der Startup rufe ich folgendes auf:
Code:
FF_ApplyOnceExt(Backgroundtasks, 1000, -1);
Der Code schaut wie folgt aus.
Code:
var int rand;
var string str;
func void Backgroundtasks()
{
// Regen Kommentare
if (LastRainCommentDay != Wld_GetDay())
{
if (Wld_IsRaining())
{
rand = r_MinMax(1, 4);
str = "$Regen";
str = ConcatStrings (str, IntToString(rand));
B_Say(hero, hero, str);
LastRainCommentDay = Wld_GetDay();
};
};
};
Da kann ich so nichts problematisches erkennen. Dass es mit FF_ApplyOnceExtGT behoben sein könnte, bezweifle ich, da die Abstürze ja bei Interaktionen mit dem Inventar auftreten. Aber wer weiß.
Du kannst das Problem mal mit Prints eingrenzen, um herauszufinden, welche Zeile den Absturz erzeugt. Alternativ kannst du das machen, in dem du den Stacktrace der AV noch weiter analysierst. Wenn du den Befehl weißt, der das Problem auslöst, können wir vielleicht besser weiterhelfen.
Ich habe einen Spielstand von einem Spieler, bei dem reproduzierbar das Spiel abstürzt, wenn ich einen Trialog führe. Warnungen und Fehlermeldungen im zSpy:
Ich hatte mir gedacht: "Trialog läuft bereits" -- da wurde vielleicht ein Trialog nicht richtig beendet vorher? Deshalb ausprobiert, einfach mal vorher TRIA_Finish auszuführen, aber das bringt das Spiel zum Absturz:
(kein Stacktrace davor im zSpy, wenn ich einfach so TRIA_Finish aufrufe, in meinem Fall über die Konsole call TRIA_Finish)
Beispiels-Trialog, bei dem das Problem auftritt (ist eine Dialog-Choice)
Code:
FUNC void DIA_ST_K3_BERENLUTHIEN_6_TORWACHE_TRIA_2()
{
var c_npc TRIA_W1; TRIA_W1 = Hlp_GetNpc(loa_mil_6969_torwache1);
var c_npc TRIA_W2; TRIA_W2 = Hlp_GetNpc(loa_mil_6981_torwache2);
TRIA_Invite(TRIA_W2);
TRIA_Start();
DIAG_Reset();
TRIA_Next(TRIA_W1);
AI_Output (other, self, "DIA_ST_K3_BERENLUTHIEN_6_TORWACHE_TRIA_2_00"); //Wir wurden unterwegs von Banditen überfallen.
AI_Output (self, other, "DIA_ST_K3_BERENLUTHIEN_6_TORWACHE_TRIA_2_01"); //(lacht) Wir? Und wo sind deine imaginären Freunde?
TRIA_Next(TRIA_W2);
AI_TurnToNpc(self, TRIA_W1);
AI_Output (self, other, "DIA_ST_K3_BERENLUTHIEN_6_TORWACHE_TRIA_2_02"); //(grinst) Lass ihn durch, den kenn ich. Und er hat offensichtlich gut gebechert.
TRIA_Next(TRIA_W1);
AI_TurnToNpc(self, hero);
AI_Output (self, other, "DIA_ST_K3_BERENLUTHIEN_6_TORWACHE_TRIA_2_03"); //Na schön, dann mal rein mit dir!
Xp(50);
DIAG_Reset();
TRIA_Finish();
AI_StopProcessInfos (self);
};
Hat jemand eine Idee, was da vor sich geht und wie man das Problem beheben / verhindern / umgehen kann?