»Es gibt Lego, es gibt Minecraft, aber nichts ist so toll wie LeGo \o/«
-Lehona
LeGo [LehonaGottfried] ist, wie aus dem Titel ersichtlich, ein Skriptpaket das auf Ikarus aufbaut. Während Ikarus grundlegende Möglichkeiten bereitstellt, wird hier der Fokus auf die praktische Anwendung gelegt. Alle enthaltenen Funktionen sind sehr einfach gehalten und müssen nicht in ein tolles Script eingeflochten werden um Sinn zu ergeben, sondern sind auch alleinstehend mächtig. Über pixelgenaues Erzeugen von Texten und Texturen auf dem Bildschirm und einem schönen Interface für Trialoge (eigentlich "Polyloge"), bis hin zu "Triggerlosen Triggerschleifen" die mit nur einer Zeile aktiviert werden können beinhaltet LeGo sicher für jeden Scripter eine interressante Erweiterung die ihm von Nutzen sein kann.
Sicher sind manche Pakete sehr speziell oder einfach nur nutzloser als andere, das liegt daran dass LeGo nicht aus einer Idee "Lass uns ein Scriptpaket machen!" entstanden ist. Ursprünglich war alles was hier zu finden ist als Grundlage für unseren Beitrag zum Modding-Contest gedacht, da Lehona und ich aber leider nicht fertig geworden sind (aus eigener Faulheit, zugegebenermaßen) lag dieser Featurehaufen noch ungeordnet und ohne Nutzen auf unseren Platten. Nun, da wir beide nette Menschen sind haben wir uns überlegt den ganzen Kram zu sortieren, kommentieren und zu erklären (was bei unserer Arbeitweise beim besten Willen nicht einfach war) und hier zur Verfügung zu stellen.
Sektenspinners zweifellos vorhandene Unterstützung sei natürlich auch noch erwähnt. Ohne ihn hätte sich der Release entweder noch um ein paar Jahren hingezogen oder es gäbe gar keinen
LeGo wird (wenn interresse besteht) laufend erweitert, nicht zuletzt wenn DU gute Vorschläge für weitere Funktionen hast, daher eröffnen wir hier mal ganz konservativ mit der Version 1.0
Zur Version 1.0 sei noch folgendes gesagt: Da LeGo mit momentan 15 Päckchen ziemlich umfangreich geworden ist können wir beide keine Fehlerfreiheit garantieren. Jedes Paket wurde bereits genutzt und sollte im Normalfall funktionieren, allerdings wurde in den letzten Tagen noch sehr viel modifiziert um es möglichst Nutzerfreundlich zu gestalten. Wenn du einen Fehler entdecken solltest (oder ein grundlosen Absturz bekommst, was auch immer ) dann schreib doch ein paar Zeilen in diesen Thread in denen du kurz erläuterst was genau du getan hast und welche der Pakete aktiv waren.
Mit Revision 88 (Interface.d und _Hashtable.d aktualisiert) wurde das Problem mit PrintScreen und den Hashtables gefixt, d.h. PrintScreen landet jetzt nicht mehr in der AI-Queue und die Hashtables crashen jetzt nicht mehr, wenn sie vergrößert werden
Ok vergiss das wieder, hatte noch die HTML-Tags drinnen, weil ich irgendwie nicht nur den Daedelus-Code, sondern den Seitenquelltext geladen habe. Jetzt geht es.
Ein Problem habe ich derzeit noch (auch schon mit älteren Versionen): Nach dem Laden eines Spielstands gibt mir der zSpy diese Fehlermeldung aus:
Code:
00:11 Info: 3 B: ---------- 95% ---------- .... <zViewProgressbar.cpp,#142>
00:11 Info: 3 B: ---------- 96% ---------- .... <zViewProgressbar.cpp,#142>
00:11 Info: 3 B: ---------- 97% ---------- .... <zViewProgressbar.cpp,#142>
00:11 Info: 3 B: ---------- 98% ---------- .... <zViewProgressbar.cpp,#142>
00:11 Info: 0 Q: Ikarus log functions now print in colour with prefix 'Q:'.
00:11 Info: 0 Q: LeGo 2.3.1 wird initialisiert.
00:11 Fault: 0 Q: [start of stacktrace]
00:11 Fault: 0 Q: MEMINT_HANDLEERROR(2, 'STR_SubStr: The end of the desired substring exceeds the end of the string.') + 62 bytes
00:11 Fault: 0 Q: MEM_WARN('STR_SubStr: The end of the desired substring exceeds the end of the string.') + 21 bytes
00:11 Fault: 0 Q: STR_SUBSTR(' ', 0, 8) + 227 bytes
00:11 Fault: 0 Q: _BIN_GETSAVEFILEPATH(1) + 69 bytes
00:11 Fault: 0 Q: _BR_LOADGAME() + 65 bytes
00:11 Fault: 0 Q: LEGO_INITALWAYS(163263) + 106 bytes
00:11 Fault: 0 Q: LEGO_INIT(160189) + 109 bytes
00:11 Fault: 0 Q: INIT_GLOBAL() + 116 bytes
00:11 Fault: 0 Q: [end of stacktrace]
00:11 Warn: 0 Q: STR_SubStr: The end of the desired substring exceeds the end of the string.
00:11 Fault: 0 Q: [start of stacktrace]
00:11 Fault: 0 Q: MEMINT_HANDLEERROR(2, 'MEM_Free: ptr is 0. Ignoring request.') + 62 bytes
00:11 Fault: 0 Q: MEM_WARN('MEM_Free: ptr is 0. Ignoring request.') + 21 bytes
00:11 Fault: 0 Q: MEM_FREE_(0) + 27 bytes
00:11 Fault: 0 Q: BR_OPENFILE('saves_SM/savegame1/SCRPTSAVE.SAV') + 219 bytes
00:11 Fault: 0 Q: _BR_LOADGAME() + 70 bytes
00:11 Fault: 0 Q: LEGO_INITALWAYS(163263) + 106 bytes
00:11 Fault: 0 Q: LEGO_INIT(160189) + 109 bytes
00:11 Fault: 0 Q: INIT_GLOBAL() + 116 bytes
00:11 Fault: 0 Q: [end of stacktrace]
00:11 Warn: 0 Q: MEM_Free: ptr is 0. Ignoring request.
00:11 Info: 0 Q: === PermMem::UnArchive ===
00:11 Info: 0 Q: Reset ALL the handles!
00:11 Info: 0 Q: Resetting done.
00:11 Info: 0 Q: Locals: Install at CREATE
00:11 Info: 0 Q: Offset is 11
00:11 Info: 0 Q: Locals: Install at _PM_LOAD
00:11 Info: 0 Q: Offset is 23
00:11 Info: 0 Q: Locals: Install at _PM_SAVESTRUCT_DELETEARR
00:11 Info: 0 Q: Offset is 11
00:11 Info: 0 Q: Locals: Install at _PM_CLASSTOINST_AUTO
00:11 Info: 0 Q: Offset is 11
00:11 Info: 0 Q: buffer used: 5188
00:11 Info: 0 Q: buffer cleaned: 5188
00:11 Info: 0 Q: objects created: 177
00:11 Info: 0 Q: objects cleaned: 177
00:11 Info: 0 Q: ellapsed time: 125
00:11 Info: 0 Q: === Done ===
00:11 Info: 0 Q: LeGo 2.3.1 wurde erfolgreich initialisiert.
00:11 Info: 0 Q: Locals: Install at FOREACHHNDL
00:11 Info: 0 Q: Offset is 17
...
Wenn ich danach ein neues handle erstelle, gibt es einen Absturz. Ne Idee womit das zusammenhängen kann?
Momentan kann ich den Absturz nicht rekonstruieren und den Fehler dementsprechend schlecht nachvollziehen
Gibt es bei denn noch eine finale Fehlermeldung (also wenn du ein Handle allozierst)? Existiert die Datei saves_SM\savegame1\SCRPTSAVE.SAV?
Die Datei existiert. Die Fehlermeldung sieht so aus, danach läuft das Spiel jedoch weiter:
Code:
00:33 Fault: 0 Q: [start of stacktrace]
00:33 Fault: 0 Q: MEMINT_HANDLEERROR(3, 'HT: A key has been assigned with two values!') + 62 bytes
00:33 Fault: 0 Q: MEM_ERROR('HT: A key has been assigned with two values!') + 21 bytes
00:33 Fault: 0 Q: _HT_INSERT(269059228, 268796076, 21) + 239 bytes
00:33 Fault: 0 Q: NEW(20560) + 91 bytes
00:33 Fault: 0 Q: MEM_CALLBYOFFSET(52753) + 22 bytes
00:33 Fault: 0 Q: LOCALS() + 3530 bytes
00:33 Fault: 0 Q: NEW(20560) + 11 bytes
...
Gelegentlich gibt es zusätzlich noch einen richtigen Absturz, ich habe keine Ahnung wann und warum.
Die Unterstützung hier bei der Benutzung von Lego ist zwar sehr lobenswert, aber ich werde es jetzt einfach so umbauen, dass ich ohne PermMem und forEachHandle auskomme. Das erspart mir eine Menge Ärger und Zeit, auch wenn ich dann 100 Zeilen mehr brauche.
Natürlich, ich will hier keinen zu irgendetwas zwingen
Leider kann ich Abstürze, die bei mir nicht auftreten und von denen ich keine Fehlermeldung bekomme, schlecht beheben. Mittlerweile rächt sich einfach, dass ich/wir damals noch nicht so viel vom Programmieren verstanden haben wie heute und eine komplette Neustrukturierung einfach zu viel des Guten wäre.
Ich hab mir das übrigens gerade nochmal angeschaut, die oberen beiden Fehlermeldungen scheinen harmlos zu sein, lassen sich aber leicht vermeiden wenn man kleine Änderungen im Lego-Code vornimmt. Die Funktionalität wird dadurch scheinbar nicht beeinflusst.
Ausschnitt aus der Saves.d
Code:
func string _BIN_GetSavefilePath(var int slot){
var string path;
var string cmd; cmd = MEM_GetCommandLine();
var string _BIN_ini;
if(!STR_len(_BIN_ini)){
MEM_Info(IntToString(STR_IndexOf(cmd, "-GAME:")));
_BIN_ini = STR_SubStr(cmd, STR_IndexOf(cmd, "-GAME:")+6, 1024);
_BIN_ini = STR_Split(_BIN_ini, ".", 0);
};
Der String cmd hat natürlich keine 1024 Zeichen, das steht wohl eher sicherheitshalber da, damit ja nicht zu wenig genommen wird. Wenn man 1024 ersetzt mit STR_len(cmd)-6 (oder so) dann kommt die Meldung nicht mehr, aber es passiert das gleiche.
Und hier aus der BinaryMachines.d aus der Funktion BR_OpenFile
_bin_ccnt hat beim ersten Laden nach dem das Spiel gestartet wurde noch den Wert 0, daher gibt Ikarus eine Warnung. Wenn man einfach noch ein if (_bin_ccnt ) davor setzt, dann kommt ebenfalls keine Warnung und es passiert das gleiche.
Das nützt zwar nichts in Sachen Stabilität, hilft aber bei der Fehlersuche, da man nicht erst durch diese Warnungen fehlgeleitet wird.
Wenn diese einmal benutzt werden, fliegt die Steinplatte auf den Boden und kann aus realitätsgründen bei der Rücktransition der Ani nicht wieder auf dem Grab platziert werden. Dalai hatte deshalb die Anzahl, die man dieses Grab benutzen darf auf einmal limitiert mit einer Variable.
Soweit so gut.
ABER: Ich möchte diesen Container öfters öffnen können, deswegen dachte ich mir, gibt es doch bestimmt ne Funktion oder Möglichkeit den Containerinhalt einer Truhe/hier Orkgrab, per LeGo zu öffnen, Also Container holen und dann?
die Mobcontainer-Klasse hat nur contains als spezielles Attribut.
oder muss man da was hooken?
Welcome
I have a small problem. I wrote a function of the compass. Function works, but there's a problem. When I change the world and return to the previous, the game is crashing. When the progress bar reaches 97%, zSpy logging :
Code:
[i] 22:34 Info: 3 B: ---------- 97% ---------- .... <zViewProgressbar.cpp,#142>
[i] 22:34 Info: 2 U: PAR: Adressing an empty Instance : MEMINT_STACKPOS.POSITION .... <zParser_Symbol.cpp,#365>
[i] 22:34 Info: 2 U: PAR: Adressing an empty Instance : MEMINT_STACKPOS.POSITION .... <zParser_Symbol.cpp,#365>
[f] 22:34 Fault: 0 Q: [start of stacktrace]
[i] 22:34 Info: 2 U: PAR: Adressing an empty Instance : ZCPARSER.STACK_STACK .... <zParser_Symbol.cpp,#365>
[i] 22:34 Info: 2 U: PAR: Adressing an empty Instance : ZCPARSER.STACK_STACKSIZE .... <zParser_Symbol.cpp,#365>
[f] 22:34 Fault: 0 Q: [UNKNOWN] +2133882429 bytes
[i] 22:34 Info: 2 U: PAR: Adressing an empty Instance : MEMINT_STACKPOS.POSITION .... <zParser_Symbol.cpp,#365>
[i] 22:34 Info: 2 U: PAR: Adressing an empty Instance : MEMINT_STACKPOS.POSITION .... <zParser_Symbol.cpp,#365>
[i] 22:34 Info: 2 U: PAR: Adressing an empty Instance : MEMINT_STACKPOS.POSITION .... <zParser_Symbol.cpp,#365>
[i] 22:34 Info: 2 U: PAR: Adressing an empty Instance : ZCPARSER.STACK_STACKSIZE .... <zParser_Symbol.cpp,#365>
[f] 22:34 Fault: 0 Q: [UNKNOWN] + 0 bytes
[f] 22:34 Fault: 0 Q: [end of stacktrace]
[f] 22:34 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.
Code:
var int Compass;
var int CompassArrow;
Func void Compass_func ()
{
var zCVob her; her = Hlp_GetNpc (hero);
if (!MEM_Game.pause_screen) && (InfoManager_HasFinished ())
{
if (!Compass)
{
Print_GetScreenSize();
Compass = View_CreatePxl (Print_Screen[PS_X] - 192, Print_Screen[PS_Y] - (Print_Screen[PS_Y] - 32), Print_Screen[PS_X] - 32, Print_Screen[PS_Y] - (Print_Screen[PS_Y] - 192));
View_SetTexture (Compass, "Compass_tex.TGA");
View_Open (Compass);
};
if (CompassArrow){delete (CompassArrow);};
CompassArrow = Sprite_CreatePxl (Print_Screen[PS_X] - 112, Print_Screen[PS_Y] - (Print_Screen[PS_Y] - 109), 159, 159, COL_White, "Compass_arrow.TGA");
Sprite_SetPrio (CompassArrow, 100);
Sprite_SetRotationSC (CompassArrow, her.trafoObjToWorld[0], her.trafoObjToWorld[8]);
}
else
{
if (Compass) {View_Close (Compass); View_Delete (Compass); Compass = 0;};
if (CompassArrow){delete (CompassArrow); CompassArrow = 0;};
};
};
I'm not experienced enough to know what is reason of crash
Is there any additional info you can provide, e.g. a screen of the Access Violation (if there is one)?
Does this only happen if you use the compass-script?
I can probably guess where the crash happens (roughly), but I can't quite say why. I'll check if I can find anything, although Sprites have been implemented by Gottfried alone.
@TheEternal: Kannst du nach dem ersten öffnen nicht einfach das Visual austauschen, so dass das Grab offen bleibt? Bzw. wenn das Visual auszutauschen ist kein Problem, wäre das eine Lösung? Kenne mich mit Animationskram nicht so aus.
Is there any additional info you can provide, e.g. a screen of the Access Violation (if there is one)?
Every time shows only window Gothic 2 has stopped working
Does this only happen if you use the compass-script?
Yes.
I can probably guess where the crash happens (roughly), but I can't quite say why. I'll check if I can find anything, although Sprites have been implemented by Gottfried alone.
@TheEternal: Kannst du nach dem ersten öffnen nicht einfach das Visual austauschen, so dass das Grab offen bleibt? Bzw. wenn das Visual auszutauschen ist kein Problem, wäre das eine Lösung? Kenne mich mit Animationskram nicht so aus.
Gut, hat funktioniert mit dieser Funktion von Sekti, wäre alleine aber nicht drauf gekommen das richtig zu schreiben.... Muss mir endlich mal die Dokumentation von Ikarus durchlesen.
Code:
funcvoid SetVobVisual(varstring vobName,varstring newVis){ var int vobPtr; vobPtr = MEM_SearchVobByName(vobName);
if (vobPtr){
const int zCVob__SetVisual = 6301312; //0x602680
CALL_zStringPtrParam(newVis);
CALL__thiscall(vobPtr, zCVob_SetVisual);
};
};
Das löst auch das Problem. Man macht dann einfach jeweil ein Grab mit offenem Deckel in Zustand S0 und beim AUstausch des visuals springt der neue Visual wieder auf Zustand S0.
Nicht alle Eigenschaften sind Bitfelder Nur, was im Namen "Bitfield" trägt, muss über Bitoperatoren gesetzt oder abgefragt werden.
Das Visual kann man (als String) allerdings nicht einfach so setzen, probier es mal mit diesem Engine-Call:
Code:
func int zCVob_SetVisual(var int vob, var string visual) {
const int zVob__SetVisual = 6301312; //602680h
CALL_zStringPtrParam(visual);
CALL__thiscall(vob, zVob__SetVisual );
};
Ich kann nicht garantieren, dass das funktioniert, aber die Methode steht in der vftable von oCMobLockable, also sollte das so stimmen.
Edit: Grml, jetzt hab ich's umsonst gemacht Freut mich aber, dass es funktioniert.
Nicht alle Eigenschaften sind Bitfelder Nur, was im Namen "Bitfield" trägt, muss über Bitoperatoren gesetzt oder abgefragt werden.
Das Visual kann man (als String) allerdings nicht einfach so setzen, probier es mal mit diesem Engine-Call:
Code:
func int zCVob_SetVisual(var int vob, var string visual) {
const int zVob__SetVisual = 6301312; //602680h
CALL_zStringPtrParam(visual);
CALL__thiscall(vob, zVob__SetVisual );
};
Ich kann nicht garantieren, dass das funktioniert, aber die Methode steht in der vftable von oCMobLockable, also sollte das so stimmen.
Edit: Grml, jetzt hab ich's umsonst gemacht Freut mich aber, dass es funktioniert.
Habs selbst gefunden, aber danke trotzdem und sorry wegen der unnötigen Arbeit.
Hab jetzt einen Bug gefunden bei der LeGo initialisierung.
Und zwar, wenn man das Spiel mit LeGo -init aufruf neu startet und darauf ein Wld_InsertNpc(npc, wp); aus einem Triggerevent aufruft, dann stürzt das Spiel ab ("deleting an already deleted object").
Wenn man vor dem Wld_insertNpc speichert und das G2 neu startet(also LeGo init weg), dann lädt und dann Wld_insertNpc per Triggerevent ausführt, stürzt es nicht ab. Also liegt es sehr wahrscheinlich an LeGo-initialisierung, die Einfluss auf die Session hat.
Ist der Bug bekannt? Gibts ne Lösung?
Habe mir damit schon einiges an Frustmomenten beschert, weil ich nicht wusste wieso das Spiel einfach so abstürzt. Und ich beim testen meist nen neues Spiel starte, um die neuen Skripts und Welt bereit zu haben.
Das klingt in der Tat sehr merkwürdig, zumal bei Wld_InsertNpc() doch gar kein Objekt gelöscht werden sollte
Ich werde mal versuchen, den Fehler zu reproduzieren.
Welcome
I have a small problem. I wrote a function of the compass. Function works, but there's a problem. When I change the world and return to the previous, the game is crashing. When the progress bar reaches 97%, zSpy logging :
Code:
[i] 22:34 Info: 3 B: ---------- 97% ---------- .... <zViewProgressbar.cpp,#142>
[i] 22:34 Info: 2 U: PAR: Adressing an empty Instance : MEMINT_STACKPOS.POSITION .... <zParser_Symbol.cpp,#365>
[i] 22:34 Info: 2 U: PAR: Adressing an empty Instance : MEMINT_STACKPOS.POSITION .... <zParser_Symbol.cpp,#365>
[f] 22:34 Fault: 0 Q: [start of stacktrace]
[i] 22:34 Info: 2 U: PAR: Adressing an empty Instance : ZCPARSER.STACK_STACK .... <zParser_Symbol.cpp,#365>
[i] 22:34 Info: 2 U: PAR: Adressing an empty Instance : ZCPARSER.STACK_STACKSIZE .... <zParser_Symbol.cpp,#365>
[f] 22:34 Fault: 0 Q: [UNKNOWN] +2133882429 bytes
[i] 22:34 Info: 2 U: PAR: Adressing an empty Instance : MEMINT_STACKPOS.POSITION .... <zParser_Symbol.cpp,#365>
[i] 22:34 Info: 2 U: PAR: Adressing an empty Instance : MEMINT_STACKPOS.POSITION .... <zParser_Symbol.cpp,#365>
[i] 22:34 Info: 2 U: PAR: Adressing an empty Instance : MEMINT_STACKPOS.POSITION .... <zParser_Symbol.cpp,#365>
[i] 22:34 Info: 2 U: PAR: Adressing an empty Instance : ZCPARSER.STACK_STACKSIZE .... <zParser_Symbol.cpp,#365>
[f] 22:34 Fault: 0 Q: [UNKNOWN] + 0 bytes
[f] 22:34 Fault: 0 Q: [end of stacktrace]
[f] 22:34 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.
Code:
var int Compass;
var int CompassArrow;
Func void Compass_func ()
{
var zCVob her; her = Hlp_GetNpc (hero);
if (!MEM_Game.pause_screen) && (InfoManager_HasFinished ())
{
if (!Compass)
{
Print_GetScreenSize();
Compass = View_CreatePxl (Print_Screen[PS_X] - 192, Print_Screen[PS_Y] - (Print_Screen[PS_Y] - 32), Print_Screen[PS_X] - 32, Print_Screen[PS_Y] - (Print_Screen[PS_Y] - 192));
View_SetTexture (Compass, "Compass_tex.TGA");
View_Open (Compass);
};
if (CompassArrow){delete (CompassArrow);};
CompassArrow = Sprite_CreatePxl (Print_Screen[PS_X] - 112, Print_Screen[PS_Y] - (Print_Screen[PS_Y] - 109), 159, 159, COL_White, "Compass_arrow.TGA");
Sprite_SetPrio (CompassArrow, 100);
Sprite_SetRotationSC (CompassArrow, her.trafoObjToWorld[0], her.trafoObjToWorld[8]);
}
else
{
if (Compass) {View_Close (Compass); View_Delete (Compass); Compass = 0;};
if (CompassArrow){delete (CompassArrow); CompassArrow = 0;};
};
};
I'm not experienced enough to know what is reason of crash
Gothic always forgets Ikarus' global variables on world change, they need to be re-inited.