Allgemein
News
News-Archiv
Partner
Netzwerk
Banner
Header
Media
Downloads
Impressum

The Elder Scrolls
Arena
Daggerfall
Spin-offs
Romane
Jubiläum
Reviews
Welt von TES
Lore-Bibliothek
Namens-
generator

FRPGs

Elder Scrolls Online
Allgemein
Fraktionen
Charakter
Kargstein
Technik
Tamriel-
Manuskript

Media

Skyrim
Allgemein
Lösungen
Tipps & Tricks
Steam-Kniffe
Review
Media
Plugins & Mods

Oblivion
Allgemein
Lösungen
Tipps & Tricks
Technik
Charakter
Media
Plugins & Mods
Kompendium

Morrowind
Allgemein
Lösungen
Tipps & Tricks
Media
Plugins & Mods

Foren
The Elder Scrolls Online
Hilfe & Diskussion

Skyrim
Hilfe & Diskussion
Plugins & Mods

Ältere TES-Spiele
TES-Diskussion
Oblivion-Plugins
Morrowind-Plugins

Community
Taverne zum Shalk
Adventures of Vvardenfell
Tales of Tamriel
Ergebnis 1 bis 15 von 15

Thema: Tutorials für das Construction Set

Baum-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #13

    Verwenden verschiedener Sprachen ohne Einsatz meherer *.esp-Dateien

    Ich begebe mich auch mal unter die Tutorial-Schreiber.

    Wie oben im Titel zu sehen wird hier nach und nach ein Tutorial entstehen, wie man ein mehrsprachiges Plugin erstellen kann, ohne für jede Sprache eine eigene *.esp zu benötigen.
    Für dieses Tutorial wird zumindest ein grundlegendes Scriptwissen vorausgesetzt, da sowohl das umbenennen der Items, als auch das feststellen der Sprache über Scripts erfolgt und ich mir nicht die Mühe machen will, dass Scripten auch noch extra zu erklären.

    Sofern man auf neue Objekte (z.B. Activators, Inventarobjekte, Zauber) verzichtet kann man das komplett mit Vanilla-Befehlen erreichen, allerdings bevorzuge ich immer die Variante mit OBSE.

    ACHTUNG:
    Ich habe in keinem Script die nötige Überprüfung nach OBSE/Pluggy eingefügt.
    Es wird davon ausgegangen, dass diese schon erfolgt sind.
    Sofern OBSE/Pluggy benötigt wird steht es dabei.




    Feststellen der Sprache
    Um die Sprache herauszufinden gibt es 4 Möglichkeiten (ich bin sicher, es gibt noch ein paar mehr, ich zähle hier aber nur diese 4 auf ):
    1. Bestimmen der Sprache durch Fragen des Users
      Einfach beim ersten Spielstart eine MessageBox und gut ist. Einziges Problem ist, dass man sich bei dieser MessageBox für eine Sprache entscheiden muss. Englisch dürfte hier die beste Wahl sein, da dass von den meisten verstanden wird.
      Das ganze könnte z.B. so aussehen:
      Code:
      scn QuDetermineLanguageScript
      
      short Stage
      short Language		;0=English, 1=German, 2=French, 3=Spanish, 4=Italian, etc.
      
      Begin Gamemode
      	if ( Stage )
      		if ( Language == -1 )
      			set Language to GetButtonPressed
      		else
      			StopQuest QuDetermineLanguage
      		enidf
      	else
      		set Language to GetButtonPressed
      		MessageBox "Which Language do you want to use?" "English" "German" "French" "Spanish" "Italian"
      	endif
      End
      Bei mir würde sich sowas nur auf English & Deutsch beschränken, einfach weil ich nicht mehr kann.
    2. Bestimmen der Sprache anhand des *.ini-Setting iLanguage unter [Controls].
      Gibt meistens verlässlich die Sprache an, steht aber eigentlich für die Tastatureinstellung (Language values: 0-English, 1-German, 2-French, 3-Spanish, 4-Italian). In Einzelfällen kann also die falsche Sprache gewählt werden.
      Benötigt den OBSE-Befehl GetNumericINISetting/con_GetINISetting.
      Code:
      scn QuDetermineLanguageScript
      
      short Language		;0=English, 1=German, 2=French, 3=Spanish, 4=Italian, etc.
      
      Begin Gamemode
      	set Language to GetNumericINISetting "iLanguage:Controls"
      	StopQuest QuDetermineLanguage
      End
    3. Bestimmen der Sprache anhand des Namens eines Vanilla-Objekts (z.B. eines Apfels)
      Funktioniert z.B. über die OBSE-Funktion CompareNames, könnte allerdings in Einzelfällen das falsche Ergebnis liefern falls ein anderes Plugin den Namen ändert.
      Code:
      scn QuDetermineLanguageScript
      
      short Language		;0=English, 1=German, 2=French, 3=Spanish, 4=Italian, etc.
      
      Begin Gamemode
      	set Language to ( ( CompareNames Apple AppleDV ) == 0 ) + ( ( ( CompareNames Apple AppleFV ) == 0 ) * 2 )	;kann noch beliebig mit weiteren Sprachen ergänzt werden
      	StopQuest QuDetermineLanguage
      End
      Unterstützt in der Form die Sprachen Englisch, Deutsch & Französich.
      AppleDV & AppleFV sind irgendwelche Objekte, die genauso heißen wie Apple in der jeweiligen Sprache.
      AppleDV heißt also Apfel, während AppleFV wahrscheinlich pomme (fragt am besten bei jemanden mit einer französischen Version nach) heißt.
    4. Bestimmen der Sprache anhand der Dateigröße der Oblivion.esm.
      Funktioniert über die Pluggy-Funktion GetFileSize. Die zu überprüfenden Werte für die Deutsche Version (Patch 1.2.0416) sind dabei 247876643 & 278038032, als RootID muss dabei natürlich 1 (Oblivion main folder) verwendet werden.
      Funktioniert absolut zuverlässig, solange der User die Oblivion.esm nicht verändert hat. Das sollte zwar eigentlich nie der Fall sein, aber User sind manchmal noch unvorhersehbarer, als Oblivion selbst.
      Code:
      scn QuDetermineLanguageScript
      
      short Language		;0=English, 1=German, 2=French, 3=Spanish, 4=Italian, etc.
      
      Begin Gamemode
      	set Language to ( ( ( GetFileSize -2000 1 ) == 247876643 ) || ( ( GetFileSize -2000 1 ) == 278038032 ) )	;Patch 1.2 ohne SI || Patch 1.2 mit SI; DV=1, alles andere =0
      	StopQuest QuDetermineLanguage
      End
      Unterstützt in der Form nur die Sprachen Englisch & Deutsch (heißt: alles Nicht-Deutsche wird Englisch).

    Bei jeder Möglichkeit sollte man meiner Meinung nach z.B. einen Konsolenbefehl einbauen, um die Sprache nachträglich zu ändern. Nur für den Fall, dass es sich um einen der Einzelfälle handelt, oder man sich später nochmal umentscheidet.
    Bei meinen Beispielen würde der so aussehen:
    Code:
    set QuDetermineLanguage.Language to X
    Wobei X für die gewünschte Sprache steht.
    Man muss dabei sicherstellen, dass dabei auch alle Werte, die damit zusammenhängen geändert werden. Wie das funktioniert beschreibe ich später.




    Anwendung
    So, jetzt habt ihr eine Variable, die euch die Sprache angibt. Das alleine nützt allerdings gar nichts, da man sie erst noch verwenden muss.

    Dialoge, Tagebucheinträge und ähnliches
    Bei Dialogen, Tagebucheinträgen, etc. funktioniert das, indem man von jedem für jede Sprache eine eigene Version hinzufügt und als zusätzliche Condition ein GetScriptVariable (bzw. GetGlobalValue falls ihr solche bevorzugt) mit Abfrage der jeweiligen Sprache hinzufügt.
    Allerdings sollte man eine Sprache (ich empfehle wieder einmal Englisch, wird einfach von den meisten Leuten verstanden) für den Fall verwenden, dass der gewählte Wert ungültig ist (heißt: die Sprache wird nicht unterstützt). Dazu schließt ihr einfach alle anderen Werte aus (Heißt: anstelle von == 0 mehrere Abfragen, wie z.B. != 1, != 2, etc.).




    Messages & MessageBoxen
    Bei Messages & MessageBoxen könnt ihr entweder im Script immer einen extra If-Block konstruieren (benötigt kein OBSE, ist aber sehr aufwendig und verschlingt eine Menge Platz), oder ihr verwendet stattdessen MessageEx & MessageBoxEx und lasst alles was Text ist durch %c darstellen. Dazu erstellt ihr für jede Sprache eine eigene Faction*, in deren Male Titles der jeweilige Text gespeichert wird. Die Faction für die verwendete Sprache speichert ihr dann in einer Ref-Variablen, welche ihr dann als ersten Parameter für %c angebt. Nachteil dieser Variante ist, dass das bei Variablen etwas kompliziert werden kann und, sofern man das als Nachteil sieht, dass es OBSE benötigt, trotzdem ist das meiner Meinung nach die zu bevorzugende Variante.

    *Man könnte anstelle der Faction auch einen Zauber mit lauter ScriptEffecten verwenden, wobei man den ScriptEffecten dann die entsprechenden Namen gibt. Ich finde die Variante mit der Faction aber weniger kompliziert und daher zu bevorzugen.

    Hier mal ein kleines Beispiel dazu:
    Ich will eine MessageBox darstellen, die dem Spieler den Wert einer Variablen mitteilt.
    Dabei nehme ich an , dass die entsprechende Faction schon der Ref-Variablen Faction der Quest QuDetermineLanguage zugewiesen wurde.
    Code:
    scn QuShowExampleMessageBox
    
    short var
    
    Begin Gamemode
    	if ( GetQuestRunning QuDetermineLanguage == 0 )
    		set var to GetRandomPercent
    		MessageBoxEx "%c%.0f", QuDetermineLanguage.Faction, 1, var	;anstelle von 1 kann auch ein anderer Parameter dargestellt werden, je nach dem in welchem Rang der Text gespeichert wurde
    	endif
    End
    Hierbei steht jetzt bei Rang 1 der englischen Faction z.B. folgendes:
    Zitat Zitat
    var has a value of
    währen bei der deutschen z.B. folgendes steht:
    Zitat Zitat
    var hat den Wert
    Wenn man jetzt von einer deutschen Sprache ausgeht und annimmt, GetRandomPercent hat 36 ausgegeben wird in der MessageBox folgendes zu lesen sein:
    Zitat Zitat
    var hat den Wert 36
    ----------------------------
    OK

    Factions & Zauber
    Hier gibt es jetzt mehrere Möglichkeiten. Entweder man erstellt für jede Sprache eine eigene Version, oder man benennt sie einfach um. Für letzteres wird OBSE benötigt.

    Um die Factions/Zauber selbst umzubenennen kann man ohne Probleme SetName(Ex) verwenden, das wirklich problematische sind hier die Einzelnen Ränge einer Faction, bzw. die ScriptEffekte eines Zaubers. Dafür benötigt man dann SetNthFactionRankNameEx, bzw. SetNthEffectItemScriptName(Ex).
    Bei Factions würde ich ganz klar für die Methode mit mehreren Factions, wo die verwendete dann anhand der Sprache ausgewählt wird, plädieren. Bei den Zaubern kommt es mir ehrlich gesagt vor allem auf die Anzahl der Skripteffekte an. Alle anderen muss man nämlich überhaupt nicht übersetzten.


    Zellen, Actors & andere Objekte
    Jetzt fehlen eigentlich nur noch Zellen, Objekte, NPCs und Kreaturen.
    Hier ist der Punkt erreicht, an dem sich die Möglichkeiten mit, bzw. ohne OBSE nicht nur im Komfort (bzw. der Möglichkeit Variablen zu verwenden) ausdrückt, sondern der bloßen Möglichkeit Objekte via Script umzubenennen.
    Mit OBSE funktioniert das ganz einfach: man verwendet SetNameEx und kann dabei sogar die gleiche Methode anwenden, wie bei den MessageBoxen. Einziger Unterschied ist, dass man das umzubenennende Objekt (bzw. den NPC/die Kreatur/die Zelle) entweder in einer Ref-Variablen zwischenspeichert und dann als letzten Parameter angibt (einzige Möglichkeit für Zellen), oder dass man eine Referenz desselben als CallingReference verwendet.

    Ohne OBSE wird das ganze etwas komplizierter. Zwar gibt es für Zellen mit SetCellFullName, sowie für NPCs und Kreaturen mit SetActorFullName Befehle diese umzubenennen, allerdings habe ich keinen für andere Objekte (z.B. Activators) gefunden.
    Sollte man nur Vanilla-Objekte verwenden kann man zwar auf ein Umbenennen von diesen Verzichten, trotzdem ist es sinnvoll zumindest die Zellen mit einem Beschreibenden Namen (z.B. Höhle) umzubenennen.
    Dazu muss man alle Namen in dem Script als String ausschreiben, was die Scriptgröße sehr schnell ansteigen lässt, so dass man wahrscheinlich sehr schnell an die Max_Script_Size stößt. Lässt sich zwar umgehen, ist aber trotzdem nervig.

    Alternativ kann man auch noch den Weg über doppelte Zellen/Objekte/etc. gehen, indem man für jede Sprache ein eigenes Objekt erstellt und alle Objekte einer nicht verwendeten Sprache via Disable entfernt. So muss man nur noch Exteriorzellen umbenennen: Objekte, NPCs & Kreaturen tauchen gar nicht auf (sind Disabled), für Interiorzellen bleibt nur die Tür zur Version mit der richtigen Sprachversion im Spiel sichtbar (Rest auch disabled), nur bei Exteriorzellen lässt sich das nicht anders beheben, aber dafür gibt es ja SetCellFullName.
    Nachteil ist halt, dass es ein massiver Aufwand ist, weil man alles doppelt & dreifach machen muss.




    Update bei nachträglicher Änderung der Sprache
    Wie vorhin schon geschrieben ist es ratsam eine Möglichkeit einzubauen, die Sprache nachträglich zu ändern. Leider ist das mit einem bloßen ändern der Language-Variablen nicht getan. Es muss noch die Faction in der Variablen getauscht, und die Objekte umbenannt werden. Für die Tagebucheinträge & Dialoge muss nichts mehr extra verwendet werden.

    Ich verwende hier als Beispiel mal den Pluggy-Methode (Dateigröße), zusammen mit einem Konsolenbefehl als Änderungsmöglichkeit:
    Code:
    scn QuDetermineLanguageScript
    
    int Init
    short Language		;0=English, 1=German, 2=French, 3=Spanish, 4=Italian, etc.
    short OldLanguage
    ref Faction
    
    Begin Gamemode
    	if ( Init )
    		if ( Language != OldLanguage )
    			set OldLanguage to Language
    			;Auswählen der Faction für MessageEx, MessageBoxEx & SetNameEx
    			if ( Language == 1 )	;German
    				set Faction to FactionDV
    			else
    				set Faction to FactionEV
    			endif
    			ActiSetNames.Activate Player 1
    		endif
    	else
    		set Language to ( ( ( GetFileSize -2000 1 ) == 247876643 ) || ( ( GetFileSize -2000 1 ) == 278038032 ) )	;Patch 1.2 ohne SI || Patch 1.2 mit SI; DV=1, alles andere =0
    
    		set OldLanguage to -1
    		set Init to 1
    	endif
    End
    Hierbei wird wieder nur die deutsche und englische Sprache unterstützt. Außerdem wird davon ausgegangen, dass ActiSetNames die Referenz eines Activators ist, in dessen Script in einem OnActivate-Block alle Objekte umbenannt werden (bzw. die Umbenennung geregelt wird).
    Natürlich kann man das auch auf die anderen Methoden übertragen.


    Das war es dann eigentlich auch schon.
    Ob es sich lohnt, den Aufwand auf sich zu nehmen um alles in einer *.esp-Datei zu haben muss jeder für sich selbst entscheiden.
    Bei größeren Projekten, die viele neue Sachen hinzufügen wage ich es zu bezweifeln, ansonsten kann es aber durchaus hilfreich sein immer nur einen Downloadlink angeben zu müssen und trotzdem alle Sprache dabei zu haben.
    Vor allem, wenn man sich dabei keine Sorgen machen muss, dass unbedarfte, ReadMe-Verweigernde User, alle vorhanden *.esp-Dateien aktivieren und dabei für komplettes Chaos sorgen. Wo nur eine *.esp vorhanden ist können nicht mehr aktiviert werden.
    Geändert von Low Post (30.12.2008 um 18:35 Uhr)

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •