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 13 von 13
  1. Beiträge anzeigen #1 Zitieren
    Ehrengarde Avatar von neocromicon
    Registriert seit
    Jan 2019
    Beiträge
    2.562
     
    neocromicon ist gerade online

    Gothic.ini und ISO 1252

    Hi,

    ich bin gerade auf ein unvorhersehbares Problem gestoßen und zwar lasse ich bestimmte String Werte in der Gothic.ini Speichern, das Problem daran sind die Sonderzeichen bzw. umlaute z.b aus "ß" macht er "\xdf" und damit kann mein Script nix anfangen.

    Jetzt würde ich sagen, das man sich den String bevor er final abgerufen wird, nochmals holt, nach z.b "\xdf" sucht und das dann wieder mit "ß" auszutauschen.
    Wäre dieser weg legitim oder geht es evtl. sogar viel einfacher?

    Edit\\: Im Script-Bin habe ich von Mud-Freak den Code Snippet "strings.d" gefunden und genau das passende gefunden:
    Code:
    /*
    * Replace first occurrence of needle in haystack and replace it
    */
    func string STR_ReplaceOnce(var string haystack, var string needle, var string replace) {
        var zString zSh; zSh = _^(_@s(haystack));
        var zString zSn; zSn = _^(_@s(needle));
        if (!zSh.len) || (!zSn.len) {
            return haystack;
        };
    
        var int startPos; startPos = STR_IndexOf(haystack, needle);
        if (startPos == -1) {
            return haystack;
        };
    
        var string destStr; destStr = "";
    
        destStr = STR_Prefix(haystack, startPos);
        destStr = ConcatStrings(destStr, replace);
        destStr = ConcatStrings(destStr, STR_Substr(haystack, startPos+zSn.len, zSh.len-(startPos+zSn.len)));
    
        return destStr;
    };
    Angewendet habe ich ihn dann so:
    Code:
        var string Ninja_Teleport_lastPosition; Ninja_Teleport_lastPosition = STR_ReplaceOnce(MEM_GetGothOpt("NINJA_TELEPORT", "lastPositionThree"),"\xdf", "ß");
        Ninja_Teleport_lastPosition = STR_ReplaceOnce(Ninja_Teleport_lastPosition,"\xe4", "ä");
        Ninja_Teleport_lastPosition = STR_ReplaceOnce(Ninja_Teleport_lastPosition,"\xf6", "ö");
        Ninja_Teleport_lastPosition = STR_ReplaceOnce(Ninja_Teleport_lastPosition,"\xfc", "ü");
        
        if (!Hlp_StrCmp(Ninja_Teleport_lastPosition, "")) {
            AI_StopProcessInfos(hero);
            AI_Teleport(hero, Ninja_Teleport_lastPosition);
            print(ConcatStrings("Pos 3:",Ninja_Teleport_lastPosition));
    Das macht genau was ich will, trotzdem bleibt meine Frage ob das auch einfacher geht, das ja nun wieder wesentlich mehr Code ist, für so ein "bisschen"
    Geändert von neocromicon (23.04.2021 um 00:35 Uhr)

  2. Beiträge anzeigen #2 Zitieren
    Provinzheld Avatar von TopLayer
    Registriert seit
    Nov 2020
    Beiträge
    286
     
    TopLayer ist offline
    Zitat Zitat von neocromicon Beitrag anzeigen
    umlaute z.b aus "ß" macht er "\xdf" und damit kann mein Script nix anfangen.
    How did you do it? I can correctly write "ß" in Gothic.ini manually and via the script.
    Do you always set the cp1252 encoding in a text editor before editing Gothic.ini or script source code?

  3. Beiträge anzeigen #3 Zitieren
    Veteran Avatar von N1kX
    Registriert seit
    Aug 2018
    Ort
    Serov
    Beiträge
    645
     
    N1kX ist offline
    And why? In the Russian encoding, instead of ß, it will be Я

    Do you have accepted forms for text in German
    ß -> ss
    ü -> ue
    ö -> oe
    ä -> ae

    I think this is already easier to find and write down.

  4. Beiträge anzeigen #4 Zitieren
    Ehrengarde Avatar von mud-freak
    Registriert seit
    Dec 2005
    Beiträge
    2.199
     
    mud-freak ist offline
    Es scheint als gäbe es sicher einen Weg die falsche Kodierung überhaupt erst vorzubeugen. Woher kommen denn die Strings ursprünglich? Sind deine Skripte korrekt kodiert?

    Was generell das Auflösen von \x.. angeht, wäre das vielleicht etwas für STR_Unescape. Bisher werden damit ausschließlich die control-Zeichen (<33) behandelt. Ich habe das mal auf die erweiterten ASCII-Zeichen (>126) ausgeweitet.


    @Lehona, ich war mal so frei auch in STR_Escape alle ASCII-Zeichen>126 zu "escapen". Ist das deiner Meinung nach legitim und im Sinne der Funktion? (Siehe hier)


    @neocromicon, um deinen Code leserlicher zu machen, bist du herzlich eingeladen, das Prefix "Ninja_" in den Symbolnamen wegzulassen (ich hatte hier dazu etwas geschrieben), vorausgesetzt die Symbolnamen sind dann noch eindeutig genug. Das ist vielleicht bei einem Patch mit Namen "Teleport" nicht wirklich sichergestellt. Insgesamt wäre ein aussagekräftigerer Patchname sicher nicht verkehrt. Vielleicht PositionTeleport oder was genau er machen wird. Gerade in den INI-Settings kannst du "Ninja_" weglassen. Ohne können merkwürdige Bezeichnungen wie "der Teleportninja" oder "der Teleportninjapatch" vermieden werden. Schließlich besteht ja kein Bezug zu Ninja.

  5. Beiträge anzeigen #5 Zitieren
    Ehrengarde Avatar von neocromicon
    Registriert seit
    Jan 2019
    Beiträge
    2.562
     
    neocromicon ist gerade online
    Zitat Zitat von mud-freak Beitrag anzeigen
    Es scheint als gäbe es sicher einen Weg die falsche Kodierung überhaupt erst vorzubeugen. Woher kommen denn die Strings ursprünglich? Sind deine Skripte korrekt kodiert?

    Was generell das Auflösen von \x.. angeht, wäre das vielleicht etwas für STR_Unescape. Bisher werden damit ausschließlich die control-Zeichen (<33) behandelt. Ich habe das mal auf die erweiterten ASCII-Zeichen (>126) ausgeweitet.
    Dann erkläre ich mal was ich hier überhaupt mache.
    Also ich habe ein Item erstellt, eine Rune die aber wie ein Brief funktioniert, beim benutzen des Items wird ein Dialog geöffnet, mit diesem kann ich mich an 3 vorher gespeicherte Positionen Teleportieren. Mitthilfe eines unter Dialogs kann ich jeweils die gewünscht Position speichern.

    Die jeweilige Position wird mit diesem Code abgerufen und gespeichert:
    Code:
    MEM_SetGothOpt("NINJA_TELEPORT", "lastPositionOne", Npc_GetNearestWP(hero));
    Dabei Speichert er dann z.b Wegpunkte die so heißen "CAD_ARI_WAYTO_HOEHLEGROß_E2_03" in der Gothic.ini so: "CAD_ARI_WAYTO_HOEHLEGRO\xdf_E2_03"
    Da geschieht auch erst in der Gothic.ini, wenn ich mir im Spiel die WP's mit print ausgebe ist alles gut, oder die werte nur für diese Session in normalen Strings speichere, dann ist das auch kein Problem. Ich will aber das die Werte auch nach einem neustart erhalten bleiben, daher benutze ich dafür halt die Gothic.ini
    Der Script selber ist in ISO-1252 gespeichert. Testweiße habe ich auch mal die Gothic.ini so konvertiert, keine Änderung.

    Zitat Zitat von mud-freak Beitrag anzeigen
    @neocromicon, um deinen Code leserlicher zu machen, bist du herzlich eingeladen, das Prefix "Ninja_" in den Symbolnamen wegzulassen (ich hatte hier dazu etwas geschrieben), vorausgesetzt die Symbolnamen sind dann noch eindeutig genug. Das ist vielleicht bei einem Patch mit Namen "Teleport" nicht wirklich sichergestellt. Insgesamt wäre ein aussagekräftigerer Patchname sicher nicht verkehrt. Vielleicht PositionTeleport oder was genau er machen wird. Gerade in den INI-Settings kannst du "Ninja_" weglassen. Ohne können merkwürdige Bezeichnungen wie "der Teleportninja" oder "der Teleportninjapatch" vermieden werden. Schließlich besteht ja kein Bezug zu Ninja.
    Da hatter mich bei genau der einen Variable erwischt :P , das war ursprünglich noch ein Globaler String, bevor ich die Gothic.ini benutzt habe. Keine Sorge ich habe mittlerweile gelernt, wann und wo ich den vollen Symbolnamen verwenden muss und wo nicht .

    Zu der zweiten Antwort, der Patch wird noch zu OwnTeleports umbenannt, ich denke das sollte eindeutiger sein und das "Ninja_Teleport" für die Gothic.ini wird noch ersetzt, jetzt wo du das so sagst lese ich es nämlich auch so

  6. Beiträge anzeigen #6 Zitieren
    Ehrengarde Avatar von mud-freak
    Registriert seit
    Dec 2005
    Beiträge
    2.199
     
    mud-freak ist offline
    Zitat Zitat von neocromicon Beitrag anzeigen
    Da hatter mich bei genau der einen Variable erwischt
    Erwischt nein; das ist ja nicht so schlimm. Es ist ja nur in deinem Interesse, dass die Symbolnamen nun mittlerweile nicht so unübersichtlich lang sein müssen.

    Zitat Zitat von neocromicon Beitrag anzeigen
    das war ursprünglich noch ein Globaler String [...] Keine Sorge ich habe mittlerweile gelernt, wann und wo ich den vollen Symbolnamen verwenden muss und wo nicht
    Was ich meine ist, dass ich diese Namenskonvention gerade neulich etwas angepasst habe, sodass eben die Namen globaler Symbole kürzer sein können, solange sie durch den Patchnamen einen unmissverständlich eindeutigen Namen haben. Lies am besten den verlinkten Post oder direkt im Ninja-Wiki nach, das habe ich neulich aktualisiert. Damit würden deine globalen Symbole alle mit "OwnTeleports_..." beginnen.


    OwnTeleports hört sich gut an und macht sich sicher auch gut in der Gothic.ini als [OwnTeleports].



    Zu deiner Absicht: Warum speicherst du das überhaupt in der Gothic.ini? Die ist übergreifend für jegliche Mods. Viel besser ist es doch den String in den Speicherstand zu speichern, siehe PM_BindString). Du könntest sogar die genauen Weltkoordinaten in Integern speichern, dann ist der Teleport sogar noch genauer.

  7. Beiträge anzeigen #7 Zitieren
    Ehrengarde Avatar von neocromicon
    Registriert seit
    Jan 2019
    Beiträge
    2.562
     
    neocromicon ist gerade online
    Zitat Zitat von mud-freak Beitrag anzeigen
    Was ich meine ist, dass ich diese Namenskonvention gerade neulich etwas angepasst habe, sodass eben die Namen globaler Symbole kürzer sein können, solange sie durch den Patchnamen einen unmissverständlich eindeutigen Namen haben. Lies am besten den verlinkten Post oder direkt im Ninja-Wiki nach, das habe ich neulich aktualisiert. Damit würden deine globalen Symbole alle mit "OwnTeleports_..." beginnen.
    Ah ok, gut das wusste ich noch nicht, werde ich mir gleich mal durchlesen!

    Zitat Zitat von mud-freak Beitrag anzeigen
    Zu deiner Absicht: Warum speicherst du das überhaupt in der Gothic.ini? Die ist übergreifend für jegliche Mods. Viel besser ist es doch den String in den Speicherstand zu speichern, siehe PM_BindString). Du könntest sogar die genauen Weltkoordinaten in Integern speichern, dann ist der Teleport sogar noch genauer.
    Ich war so auf die ini fixiert das ich daran garnicht gedacht habe, das wäre die wesentlich bessere Lösung, so kann man den Patch auch in mehreren Mods gleichzeitig benutzen (Spine), ohne das Problem zu haben das man den Patch nur 1x verwenden kann und alles immer überschreiben würde.

    Zum Speichern der genauen Weltkoordinaten ist damit "Npc_SetTeleportPos(NPC)" gemeint? Ansonsten kann ich keine andere Funktion finden die das macht, jedenfalls nicht in Externals.d, in LeGo habe ich jedenfalls nix gefunden.

  8. Beiträge anzeigen #8 Zitieren
    Ehrengarde Avatar von mud-freak
    Registriert seit
    Dec 2005
    Beiträge
    2.199
     
    mud-freak ist offline
    Bevor du zu viel Arbeit investierst, schau mal nach. Ich meine es gab vielleicht sogar schon ein Union-Plugin, das etwas sehr ähnlich zu deinem Vorhaben schon realisiert hat.

  9. Beiträge anzeigen #9 Zitieren
    Ehrengarde Avatar von neocromicon
    Registriert seit
    Jan 2019
    Beiträge
    2.562
     
    neocromicon ist gerade online
    Von diesem Plugin kommt sogar meine Idee her .

    Ich habe mich deshalb daran gesetzt, da a.) nicht jeder Union nutzt und b.) es mir optisch nicht zusagt bzw. wie es generell in die Welt integriert ist.
    Klar es ist zwar schon nice, das man da seine eigenen Namen geben kann und mehr Positionen hat, aber soweit ich weiß verlangt es dafür nicht mal Mana.

    Mein Patch wiederum will 40 Mana pro Teleport und es ist mit Absicht auf 3 Positionen begrenzt, so ist es nicht ganz so "cheat mäßig"

    Edit:\\ So an die X,Y,Z Coordinaten des Helden komme ich nun erfolgreich heran, jetzt nur noch die Teleport Routine Bauen
    Geändert von neocromicon (23.04.2021 um 17:12 Uhr)

  10. Beiträge anzeigen #10 Zitieren
    Ehrengarde Avatar von neocromicon
    Registriert seit
    Jan 2019
    Beiträge
    2.562
     
    neocromicon ist gerade online
    So ich bin etwas am verzweifeln .

    Entweder, je nach Mod, lande ich bei 0,0,0 oder die Camera bleibt an Ort und stelle und der Held verschwindet (vermutlich auch 0,0,0)
    Ich speichere die Koordinaten als Array, während dem Speichern zeigt er mir die richtigen Koordinaten an und wenn ich sie zum Teleportieren verwende kommen auch wieder die richtigen Koordinaten dabei heraus und trotzdem klappt es nicht. Eine Cheat Eingabe mit "goto pos" und den Koordinaten die er mir ausspuckt klappt einwandfrei.

    Hier der Code zu dem ganzen:
    Code:
    const int OwnTeleports_lastPositionOne = 0;
    const int OwnTeleports_lastPositionTwo = 0;
    const int OwnTeleports_lastPositionThree = 0;
    
    const int sizeof_zVEC3 = 12;
    
    func void OwnTeleports_BindStrings() {
        PM_BindInt(OwnTeleports_lastPositionOne);
        PM_BindInt(OwnTeleports_lastPositionTwo);
        PM_BindInt(OwnTeleports_lastPositionThree);
    };
    
    func int OwnTeleports_getHeroPos() {
        var oCNPC her; her = Hlp_GetNpc(hero);
        var int pos[3];
        // X-Koordinate
        var int x_float; x_float = her._zCVob_trafoObjToWorld[zCVob_trafoObjToWorld_X];
        pos[0] = roundf(x_float);
        // Y-Koordinate
        var int y_float; y_float = her._zCVob_trafoObjToWorld[zCVob_trafoObjToWorld_Y];
        pos[1] = roundf(y_float);
        // Z-Koordinate
        var int z_float; z_float = her._zCVob_trafoObjToWorld[zCVob_trafoObjToWorld_Z];
        pos[2] = roundf(z_float);
     
        return _@(pos);
    };
    
    func void OwnTeleports_saveHeroPos(var int posPtr, var int lastPosNumber) { 		
        if (lastPosNumber == 1) {
            OwnTeleports_lastPositionOne = posPtr;
        } else if (lastPosNumber == 2) {
            //OwnTeleports_lastPositionTwo = _@(dirVec);
        } else if (lastPosNumber == 3) {
            //OwnTeleports_lastPositionThree = _@(dirVec);
        };	
    };
    
    func void OwnTeleports_AI_TeleportPos(var int posNumber) {	
        var int dirVec[3];
        var int dirPtr; dirPtr = _@(dirVec);
    	
        var oCNPC her; her = Hlp_GetNpc(hero);
        if (posNumber == 1) {
            MEM_CopyBytes(OwnTeleports_lastPositionOne, dirPtr, sizeof_zVEC3);
            her._zCVob_trafoObjToWorld[zCVob_trafoObjToWorld_X] = dirVec[0];
            print(IntToString(dirVec[0])); //STIMMT
            her._zCVob_trafoObjToWorld[zCVob_trafoObjToWorld_Y] = dirVec[1];
            print(IntToString(dirVec[1])); //STIMMT
            her._zCVob_trafoObjToWorld[zCVob_trafoObjToWorld_Z] = dirVec[2];
            print(IntToString(dirVec[2])); //STIMMT
        } else if (posNumber == 2) {
            MEM_CopyBytes(OwnTeleports_lastPositionTwo, dirPtr, sizeof_zVEC3);
            her._zCVob_trafoObjToWorld[zCVob_trafoObjToWorld_X] = dirVec[0];
            her._zCVob_trafoObjToWorld[zCVob_trafoObjToWorld_Y] = dirVec[1];
            her._zCVob_trafoObjToWorld[zCVob_trafoObjToWorld_Z] = dirVec[2];
        } else if (posNumber == 3) {
            MEM_CopyBytes(OwnTeleports_lastPositionThree, dirPtr, sizeof_zVEC3);
            her._zCVob_trafoObjToWorld[zCVob_trafoObjToWorld_X] = dirVec[0];
            her._zCVob_trafoObjToWorld[zCVob_trafoObjToWorld_Y] = dirVec[1];
            her._zCVob_trafoObjToWorld[zCVob_trafoObjToWorld_Z] = dirVec[2];
        };
    };
    Und hier noch wie ich es Abrufe:
    Speichern (Dialog Box):
    Code:
    func void DIA_OwnTeleports_getLastPositionOne_Info() {
        OwnTeleports_saveHeroPos(OwnTeleports_getHeroPos(), 1);
        
        //DEBUG
        var oCNPC her; her = Hlp_GetNpc(hero);
        var int pos[3];
        // X-Koordinate
        var int x_float; x_float = her._zCVob_trafoObjToWorld[zCVob_trafoObjToWorld_X];
        pos[0] = roundf(x_float);
        // Y-Koordinate
        var int y_float; y_float = her._zCVob_trafoObjToWorld[zCVob_trafoObjToWorld_Y];
        pos[1] = roundf(y_float);
        // Z-Koordinate
        var int z_float; z_float = her._zCVob_trafoObjToWorld[zCVob_trafoObjToWorld_Z];
        pos[2] = roundf(z_float);
        
        var string posHero;
        posHero = ConcatStrings("X: ", IntToString(pos[0]));
        posHero = ConcatStrings(posHero, " Y: ");
        posHero = ConcatStrings(posHero, IntToString(pos[1])); 
        posHero = ConcatStrings(posHero, " Z: ");
        posHero = ConcatStrings(posHero, IntToString(pos[2]));
        
        print(posHero);
        //DEBUG ENDE
        
        print("Position gespeichert");
    };
    Laden (Dialog Box):
    Code:
    func void DIA_OwnTeleports_lastPositionOne_Info() {
        if (OwnTeleports_lastPositionOne > 0) {
            if (self.attribute[ATR_MANA] > OwnTeleports_Cost - 1) {
                AI_StopProcessInfos(self);
                OwnTeleports_AI_TeleportPos(1);
                
                Wld_PlayEffect("spellFX_Teleport_RING",self,self, 0, 0, 0, FALSE );
                Snd_Play ("MFX_TELEPORT_CAST");
            
                self.attribute[ATR_MANA] = self.attribute[ATR_MANA] - OwnTeleports_Cost;
                self.aivar[AIV_INVINCIBLE] = FALSE; //Gegner greifen wieder an
                CreateInvItem(self, NINJA_ITRU_TELEPORTER);
            } else {
                print("Nicht genug Mana");
            };
        } else {
            print("Keine Position gespeichert");
        };
    };
    
    
    Geändert von neocromicon (23.04.2021 um 19:28 Uhr)

  11. Beiträge anzeigen #11 Zitieren
    Dea
    Registriert seit
    Jul 2007
    Beiträge
    10.447
     
    Lehona ist offline
    Ich habe jetzt nur grob drübergeschaut, aber du speicherst die Koordinaten als Integer via roundf und trägst dann genau diesen Wert wieder in die TrafoMatrix ein, oder? Das geht nicht, weil du da einen Float eintragen musst. Du müsstest also mkf(dirPos[x]) in die TrafoMatrix schreiben.

  12. Beiträge anzeigen #12 Zitieren
    Ehrengarde Avatar von neocromicon
    Registriert seit
    Jan 2019
    Beiträge
    2.562
     
    neocromicon ist gerade online
    Zitat Zitat von Lehona Beitrag anzeigen
    Ich habe jetzt nur grob drübergeschaut, aber du speicherst die Koordinaten als Integer via roundf und trägst dann genau diesen Wert wieder in die TrafoMatrix ein, oder? Das geht nicht, weil du da einen Float eintragen musst. Du müsstest also mkf(dirPos[x]) da speichern.
    Perfekt danke, das war des Rätsels Lösung!
    Aus "her._zCVob_trafoObjToWorld[zCVob_trafoObjToWorld_X] = dirVec[0];" wird "her._zCVob_trafoObjToWorld[zCVob_trafoObjToWorld_X] = mkf(dirVec[0]);

    Bei meiner Fehlersuche war ich bereits an dem Punkt das es daran liegt das ein einfach "= Wert" nicht reicht. Addieren, Subtrahieren, das war alles kein Problem.
    Was bedeutet mkf eigentlich? Schon oft gelesen aber nie verstanden was da bewirken soll.

  13. Beiträge anzeigen #13 Zitieren
    Dea
    Registriert seit
    Jul 2007
    Beiträge
    10.447
     
    Lehona ist offline
    Zitat Zitat von neocromicon Beitrag anzeigen
    Perfekt danke, das war des Rätsels Lösung!
    Aus "her._zCVob_trafoObjToWorld[zCVob_trafoObjToWorld_X] = dirVec[0];" wird "her._zCVob_trafoObjToWorld[zCVob_trafoObjToWorld_X] = mkf(dirVec[0]);

    Bei meiner Fehlersuche war ich bereits an dem Punkt das es daran liegt das ein einfach "= Wert" nicht reicht. Addieren, Subtrahieren, das war alles kein Problem.
    Was bedeutet mkf eigentlich? Schon oft gelesen aber nie verstanden was da bewirken soll.
    Das steht für makefloat. Ein Integer 3 ist nicht das gleich wie Float 3.0. Floats kannst du auch nicht so einfach von einander abziehen etc., dafür braucht man die entsprechenden Funktion subf, addf, ...

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