! ===========================================================================
!   Inform Language Definition File: German 011122
!
!   (c) Graham Nelson 1997, 1998, 1999
!
!   Define the constant DIALECT_US before including "Parser" to
!   obtain American English
! ---------------------------------------------------------------------------
!   Deutsch von (c) Toni Arnold 1997/98/99
!   Schlierenberg 22, 8048 Zuerich, Switzerland
!
!   Deutsche Serial No 991216
!
! Teile davon korrigiert und ergaenzt mit der library von Ralf Herrman.
!
! This library is free software; you can redistribute it and/or modify it under
! the terms of the GNU Library General Public License as published by the Free
! Software Foundation; either version 2 of the License, or (at your option) any
! later version.
!
! This library is distributed in the hope that it will be useful, but without
! any warranty; without even the implied warranty of merchantability or fitness
! for a particular purpose. See the GNU Library General Public License for more
! details.
!
! You should have received a copy of the GNU Library General Public License
! along with this library; if not, write to the Free Software Foundation, Inc.,
! 675 Mass Ave, Cambridge, MA 02139, USA.
!
!   
!   
System_file;
! ---------------------------------------------------------------------------
!   Part I.   Preliminaries
! ---------------------------------------------------------------------------
!Constant EnglishNaturalLanguage;   ! Needed to keep old pronouns mechanism
! gibt wueste runtime-errors (14) wenn das nicht auskommentiert wird :-(

!Um die Neue Rechtschreibung zu aktivieren, bitte vor dem Includen von
!"parser.h" die Konstante R_NEU setzen!

#ifndef R_NEU;
	Constant R_ALT;		!Alte Rechtschreibung als Defaultwert
	Constant C_DASS "daß ";
#ifnot;
	Constant C_DASS "dass ";
#endif;

Constant LanguageVersion
        = "Offizielle deutsche Inform-Library, Release 16, Serial 021002";

! ParserTrace: 0=off, 1=print string after LanguageToInformese, 
!                     2=ASCII-List (useful for character hacking)
#ifdef DEBUG;
  Constant ParserTrace = 0;
#endif;


! Declaration of accented letters in German
! -----------------------------------------
!Zcharacter 'ä';     ! ae-sign
!Zcharacter 'ö';     ! oe-sign
!Zcharacter 'ü';     ! ue-sign
!Zcharacter 'Ä';     ! AE-sign
!Zcharacter 'Ö';     ! OE-sign
!Zcharacter 'Ü';     ! UE-sign
!Zcharacter 'ß';     ! sz-sign for German German, not used



! ----------------------------------
Include "tgerman";
! A German Extension by Toni Arnold
! ----------------------------------

Class  CompassDirection
  with article 0, number 0, dekl 7,
  	before [;
  		LookUnder: "Die Wand ist am Boden festgemacht.";
  	],
  has  scenery female;
Object Compass "compass" has concealed;

IFNDEF WITHOUT_DIRECTIONS; 		! from Max Kalus
CompassDirection -> n_obj "Norden"
        with name 'n//' 'nord' 'norden' 'noerdlich',
		dekl 1, door_dir n_to, has male;
CompassDirection -> s_obj "Süden"
        with name 's//' 'sued' 'sueden' 'suedlich',    dekl 1, door_dir s_to, has male;
CompassDirection -> e_obj "Osten"
        with name 'o//' 'e//' 'ost' 'osten' 'oestlich',     dekl 1, door_dir e_to, has male;
CompassDirection -> w_obj "Westen"
        with name 'w//' 'west' 'westen' 'westlich',     dekl 1, door_dir w_to, has male;
CompassDirection -> ne_obj "Nordosten"
        with name 'no' 'ne' 'nordost' 'nordosten' 'nordoestlich', dekl 1, door_dir ne_to, has male;
CompassDirection -> nw_obj "Nordwesten"
        with name 'nw' 'nordwest' 'nordwesten' 'nordwestlich', dekl 1, door_dir nw_to, has male;
CompassDirection -> se_obj "Südosten"
        with name 'so' 'se' 'suedost' 'suedosten' 'suedoestlich', dekl 1, door_dir se_to, has male;
CompassDirection -> sw_obj "Südwesten"
        with name 'sw' 'suedwesten' 'suedwestlich', dekl 1, door_dir sw_to, has male;
CompassDirection -> u_obj "oben"
        with name 'h//' 'rauf' 'hinauf' 'herauf' 'hoch',    dekl 1, door_dir u_to, has neuter;
CompassDirection -> d_obj "unten"
        with name 'r//' 'runter' 'hinunter' 'herunter',
		door_dir d_to, dekl 1, has neuter;

CompassDirection -> out_obj "außen"
                    with                               door_dir out_to;
CompassDirection -> in_obj "innen"
                    with                               door_dir in_to;

ENDIF;

! ---------------------------------------------------------------------------
!   Part II.   Vocabulary
! ---------------------------------------------------------------------------

! Problem: these are parsed *before* LanguageToInformese
! -> no support for accented chars

Constant AGAIN1__WD   = 'again';
Constant AGAIN2__WD   = 'g//';
Constant AGAIN3__WD   = 'nochmal';
Constant OOPS1__WD    = 'oh';
Constant OOPS2__WD    = 'oops';
Constant OOPS3__WD    = 'huch';
Constant UNDO1__WD    = 'undo';
Constant UNDO2__WD    = 'zurueck';
Constant UNDO3__WD    = 'u//';

Constant ALL1__WD     = 'alle';
Constant ALL2__WD     = 'alles';
Constant ALL3__WD     = 'jede';
Constant ALL4__WD     = 'jedes';
Constant ALL5__WD     = 'beide';

Constant AND1__WD     = 'und';
Constant AND2__WD     = 'und';
Constant AND3__WD     = 'und';
Constant BUT1__WD     = 'aber';
Constant BUT2__WD     = 'ausser';
Constant BUT3__WD     = 'ohne';
Constant ME1__WD      = 'mich';
Constant ME2__WD      = 'dich';
Constant ME3__WD      = 'mir';
Constant OF1__WD      = 'von';
Constant OF2__WD      = 'aus';
Constant OF3__WD      = 'von';
Constant OF4__WD      = 'von';
Constant OTHER1__WD   = 'anderer';
Constant OTHER2__WD   = 'andere';
Constant OTHER3__WD   = 'anderes';
Constant THEN1__WD    = 'dann';
Constant THEN2__WD    = 'sodann';
Constant THEN3__WD    = 'danach';

Constant NO1__WD      = 'n//';
Constant NO2__WD      = 'nein';
Constant NO3__WD      = 'nein';
Constant YES1__WD     = 'j//';
Constant YES2__WD     = 'ja';
Constant YES3__WD     = 'y//';

Constant AMUSING__WD  = 'lustig';
Constant FULLSCORE1__WD = 'volle';
Constant FULLSCORE2__WD = 'punkte';
Constant QUIT1__WD    = 'e//';
Constant QUIT2__WD    = 'ende';
Constant RESTART__WD  = 'neustart';
Constant RESTORE__WD  = 'laden';




Array LanguagePronouns table

   !  word       possible GNAs                   connected
   !             to follow:                      to:
   !             a     i
   !             s  p  s  p
   !             mfnmfnmfnmfn                 

      'er'     $$100000100000                    NULL   ! mask-nom-sg
      'sie'    $$010111010111                    NULL   ! fem-nom-sg, plur all
      'es'     $$001000001000                    NULL   ! neutr-sg
      'ihn'    $$100000100000                    NULL   ! mask-sg-akk
      'ihm'    $$101000101000                    NULL   ! mask&neutr-sg-dat
      'ihnen'  $$000111000111                    NULL   ! dat-pl
      'spez.'  $$111000111000			 NULL;	! special for 'darauf'

Array LanguageDescriptors table

   !  word       possible GNAs   descriptor      connected
   !             to follow:      type:           to:
   !             a     i
   !             s  p  s  p
   !             mfnmfnmfnmfn  
                             
      'der'    $$110111110111    DEFART_PK       NULL   ! fem-dat-plu
      'die'    $$010111010111    DEFART_PK       NULL   ! plu=all
      'das'    $$001000001000    DEFART_PK       NULL               
      'dem'    $$101000101000    DEFART_PK       NULL
      'den'    $$100111100111    DEFART_PK       NULL   ! plu=all
      'des'    $$101000101000    DEFART_PK       NULL   ! gen
      
      'einen'  $$100000100000    INDEFART_PK     NULL   ! mask
      'ein'    $$101000101000    INDEFART_PK     NULL   ! mask & neutr
      'einem'  $$101000101000    INDEFART_PK     NULL   ! mask & neutr
      'eine'   $$010000010000    INDEFART_PK     NULL   ! fem
      'einer'  $$010000010000    INDEFART_PK     NULL
      'eines'  $$101000101000    INDEFART_PK     NULL   ! gen
    
    'dies'     $$001000001000    POSSESS_PK      0    ! Demonstrativpronomen
    'diese'    $$010111010111    POSSESS_PK      0
    'dieser'   $$110111110111    POSSESS_PK      0
    'diesem'   $$101000101000    POSSESS_PK      0
    'diesen'   $$100111100111    POSSESS_PK      0   
    'dieses'   $$101000101000    POSSESS_PK      0    ! gen   

     'jene'    $$010111010111    POSSESS_PK      1
     'jener'   $$110111110111    POSSESS_PK      1
     'jenem'   $$101000101000    POSSESS_PK      1
     'jenen'   $$100111100111    POSSESS_PK      1 
     'jenes'   $$101000101000    POSSESS_PK      1    ! gen   
     
      'mein'   $$101000101000    POSSESS_PK      0    ! Possesivpronomen
      'meine'  $$010111010111    POSSESS_PK      0
      'meiner' $$010111010111    POSSESS_PK      0
      'meinem' $$101000101000    POSSESS_PK      0
      'meinen' $$100111100111    POSSESS_PK      0
      'meines' $$101000101000    POSSESS_PK      0   

    'sein'     $$001000001000    POSSESS_PK      'him'  ! Poss. mask
    'seine'    $$010111010111    POSSESS_PK      'him'
    'seiner'   $$110111110111    POSSESS_PK      'him'
    'seinem'   $$101000101000    POSSESS_PK      'him'
    'seinen'   $$100111100111    POSSESS_PK      'him'
    'seines'   $$101000101000    POSSESS_PK      'him'
         

     'ihr'     $$001000001000    POSSESS_PK      'her'  ! Poss. fem
     'ihre'    $$010111010111    POSSESS_PK      'her'
     'ihrer'   $$110111110111    POSSESS_PK      'her'
     'ihrem'   $$101000101000    POSSESS_PK      'her'
     'ihren'   $$100111100111    POSSESS_PK      'her'
     'ihres'   $$101000101000    POSSESS_PK      'her'


      'deren'  $$111111111111    POSSESS_PK      'them'
     'dessen'  $$111111111111    POSSESS_PK      'it'


      'hell'    $$111111111111    light           NULL
   'erleuchtet' $$111111111111    light           NULL
     'dunkel'   $$111111111111    (-light)        NULL;


Array LanguageNumbers table
    'ein' 1 'zwei' 2 'drei' 3 'vier' 4 'fuenf' 5
    'sechs' 6 'sieben' 7 'acht' 8 'neun' 9 'zehn' 10
    'elf' 11 'zwoelf' 12 'dreizehn' 13 'vierzehn' 14 'fuenfzehn' 15
    'sechzehn' 16 'siebzehn' 17 'achtzehn' 18 'neunzehn' 19 
    'zwanzig' 20;

! ---------------------------------------------------------------------------
!   Part III.   Translation
! ---------------------------------------------------------------------------

! For GLULX the input char buffer is as follows
!buffer-->0      seems to be the number of characters typed by the player
!buffer->n       seems to be a byte-array of chars starting with pos 4
! For GLULX the parse-buffer is as follows:
!parse-->0       seems to be the number of words
!parse-->(x*3+1) seems to be the dictionary entry of word x
!parse-->(x*3+2) seems to be the number of chars word x takes 
!parse-->(x*3+3) seems to be the effective position of word x in buffer-->y

[ LanguageToInformese;
	PreProcessGerman();
	ProcessGermanVerbs();
	ProcessGermanUmlauts();
	ProcessGermanShorties();
	ProcessGermanSuffixes();
#ifdef DEBUG;
	ShowGermanDebug();
#endif;
];

! PreProcessGerman
! Routine, with is called first to do some dirty work
[ PreProcessGerman  x;
#ifndef NO_PUNCTUATION;
    x=0; !Warnung über unbenutze Variable (wenn TARGET_ZCODE,
    !PUNCTUATION gesetzt ist) verhindern
#endif;

! Glulx does not lower the ASCII-chars, so do it now
#ifdef TARGET_GLULX;
for (x = WORDSIZE: x < WORDSIZE + (buffer-->0): x++) {
  buffer->x = glk_char_to_lower(buffer->x);
}
#endif; ! TARGET_
	
#ifdef NO_PUNCTUATION;
#ifdef TARGET_ZCODE;
!Eingefügt von Max Kalus
!ändert alle "?", "!" und Anführungszeichen in Leerzeichen
   for (x=2:x<2+buffer->1:x++)
      if (buffer->x == '?' or '!' or '"' or 39) buffer->x = ' ';
#ifnot; ! TARGET_GLULX
   for (x = 0: x < (parse-->0 - 1): x++) {
      if (buffer->(parse-->(x*3+3)) == '?' or '!' or '"' or 39) buffer->x = ' ';
#endif; ! TARGET_
#endif; ! NO_PUNCTUATION

];

! ProcessGermanVerbs
! Routine to informese German verbs
[ ProcessGermanVerbs  x verbend flag;

#ifdef TARGET_ZCODE;
! 1. Pass: delete the optional "e" at the end of each german verb
! first look, if this is a command ("wilder drache, speie feuer") 
! the little problem is that the comma has to be found first because
! many names can be used to identify the target object
! if it is, remove the "e" from the actual verb not the nouns
for (x = 0: x < (parse->1 - 1): x++) {	! loop through every word except last word
  if (buffer->(parse->(x*4+5)) == ',') { 	! if comma detected
       verbend = parse->((x+1)*4+4) + parse->((x+1)*4+5) - 1; ! next word is verb
       if (buffer->verbend == 'e' && (parse->((x+1)*4+4) > 2)) buffer->verbend = ' ';
       flag = 1;	!set flag
  };
};

! now delete the optional "e" at the end of each german verb
verbend = parse->4 + parse->5 - 1; ! wordpos + wordlen of word 0 -1
if ((buffer->verbend == 'e') && (parse->4 > 2) && (flag ~= 1)) buffer->verbend = ' ';
                           ! ^ this is needed for 'e' as a compass dir

#ifnot; ! TARGET_GLULX
verbend = parse-->2 + parse-->3 - 1;
for (x = 0: x < (parse-->0 - 1): x++) {
  if (buffer->(parse-->(x*3+3)) == ',') {
       verbend = parse-->((x+1)*3+2) + parse-->((x+1)*3+3) - 1;
       if (buffer->verbend == 'e') buffer->verbend = ' ';
       flag = 1;
  };
};      
if ((buffer->verbend == 'e') && (parse-->3 > 2) && (flag ~= 1)) buffer->verbend = ' ';
#endif; ! TARGET_

];

! ProcessGermanUmlauts
! Routine to convert Umlauts to ASCII-Equivalents
[ ProcessGermanUmlauts  x;
! 2. Pass (afterwards because of confusing with "süd" -> "sued" -> "su d" 
!    Replace DOS-German Umlauts by their ASCII-Transcriptions to
!    get the lexicon work. 

#ifdef TARGET_ZCODE;
for (x = 2: x < 2 + buffer->1: x++) {  ! "ZSCII"-Chars
  switch(buffer->x)
  {161: buffer->x = 's';               ! replace german sz with ss
        LTI_Insert(x+1, 's');
   155: buffer->x = 'a';               ! replace german ä with ae
        LTI_Insert(x+1, 'e');
   156: buffer->x = 'o';               ! replace german ö with oe
        LTI_Insert(x+1, 'e');
   157: buffer->x = 'u';               ! replace german ü with ue
        LTI_Insert(x+1, 'e');
  }
}
#ifnot; ! TARGET_GLULX
for (x = WORDSIZE: x < WORDSIZE + buffer-->0: x++) {     ! ISO-Latin-1
  switch(buffer->x)
  {223: buffer->x = 's';               ! replace german sz with ss
        LTI_Insert(x+1, 's');
   228: buffer->x = 'a';               ! replace german ä with ae
        LTI_Insert(x+1, 'e');
   246: buffer->x = 'o';               ! replace german ö with oe
        LTI_Insert(x+1, 'e');
   252: buffer->x = 'u';               ! replace german ü with ue
        LTI_Insert(x+1, 'e');
  }
}
#endif; ! TARGET_

#ifdef TARGET_ZCODE;
@tokenise buffer parse; 	! othwerwise parse->x is wrong
#ifnot; ! TARGET_GLULX;
Tokenise__ (buffer, parse);
#endif; ! TARGET_;
];

! ProcessGermanShorties
! Routine to informese German verbs
[ ProcessGermanShorties x at word;
! 3. Pass: replace "im" by "in dem" and "am" by "an dem"

#ifdef TARGET_ZCODE;
for (x=0:x<parse->1:x++)  ! loop through every word
{
  word = parse-->(x*2+1);
  at = parse->(x*4+5);
#ifnot; ! TARGET_GLULX;
for (x=0:x<parse-->0:x++)
{
  word = parse-->(x*3+1);
  at = parse-->(x*3+3);
#endif; ! TARGET_;

  if (word == 'im')
  { buffer->(at+1) = 'n';
    LTI_Insert(at+2, ' ');
    LTI_Insert(at+3, 'd');
    LTI_Insert(at+4, 'e');
    LTI_Insert(at+5, 'm');
    break;
  }

  if (word == 'am')
  { buffer->(at+1) = 'n';
    LTI_Insert(at+2, ' ');
    LTI_Insert(at+3, 'd');
    LTI_Insert(at+4, 'e');
    LTI_Insert(at+5, 'm');
    break;
  }

  if (word == 'zum')
  { buffer->(at+2) = ' ';
    LTI_Insert(at+3, 'd');
    LTI_Insert(at+4, 'e');
    LTI_Insert(at+5, 'm');
    break;
  } 

  if (word == 'zur')
  { buffer->(at+2) = ' ';
    LTI_Insert(at+3, 'd');
    LTI_Insert(at+4, 'e');
    LTI_Insert(at+5, 'r');
    break;
  }  
  
  ! replace "ins" by "in das" und "ans" by "an das"
  
  if (word == 'ins')
  { buffer->(at+2) = ' ';
    LTI_Insert(at+3, 'd');
    LTI_Insert(at+4, 'a');
    LTI_Insert(at+5, 's');
    break;
  }
  
  if (word == 'ans')
  { buffer->(at+2) = ' ';
    LTI_Insert(at+3, 'd');
    LTI_Insert(at+4, 'a');
    LTI_Insert(at+5, 's');
    break;
  }

  ! replace "vom" by "von dem"
  if (word == 'vom')
  { buffer->(at+2) = 'n';
    LTI_Insert(at+3, ' ');
    LTI_Insert(at+4, 'd');
    LTI_Insert(at+5, 'e');
    LTI_Insert(at+6, 'm');
    break;
  } 
}


#ifdef TARGET_ZCODE;
@tokenise buffer parse;	! othwerwise parse->x is wrong
#ifnot; ! TARGET_GLULX;
Tokenise__ (buffer, parse);
#endif; ! TARGET_;

];

#ifdef USE_OLD_GERMAN_SUFFIX_ROUTINE;
    
!ProcessGermanSuffixes
!Routine to cut off German suffixes, but leave things like 'se' alone
[ ProcessGermanSuffixes  x at end word len;
! 4. Pass: make lemmas out of inflected nouns
!          -> this is equal to removing any suffixes
!          -> on parsing case or number or gender is not looked at at all
!          -> Umlaute (ä as 'ae') have to be entered separately in 
!              the names - property
!  List of (most) german noun suffixes:
!  e n s se ses en er ern 

#ifdef TARGET_ZCODE;
for (x=0:x<parse->1:x++)
{
  word = parse-->(x*2+1);
  if (word == 0)                 ! if word not recognized
  {
    len = parse->(x*4+4);
    at = parse->(x*4+5);
#ifnot; ! TARGET_GLULX
for (x=0:x<parse-->0:x++)
{
  word = parse-->(x*3+1);
  if (word == 0)
  {
    len = parse-->(x*3+2);
    at = parse-->(x*3+3);
#endif; ! TARGET_

    end = at+len-1;              ! last letter of the word

!Zusatz MK:
!Falls das Wort nur zwei oder so Buchstaben hat, dann nicht weiter ändern: Behebt Fehler mit "se" "ne", etc.

! --- suffix "ern" ---
     if ((buffer->end == 'n') && 
        (buffer->(end-1) == 'r') &&
        (buffer->(end-2) == 'e') &&
        (len > 4) &&
        DictionaryLookup(buffer+at,len-3) > 0) ! word without suffix in lex
     {
      buffer->end = ' ';           ! remove suffix
      buffer->(end-1) = ' ';
      buffer->(end-2) = ' ';
     }

! --- suffix "ses" ---
     if ((buffer->end == 's') && 
        (buffer->(end-1) == 'e') &&
        (buffer->(end-2) == 's') &&
        (len > 4) &&
       DictionaryLookup(buffer+at,len-3) > 0)
     {
      buffer->end = ' ';
      buffer->(end-1) = ' ';
      buffer->(end-2) = ' ';
     }


! --- suffix "se" ---
   if ((buffer->end == 'e') &&
        (buffer->(end-1) == 's') &&
        (len > 3) &&
        DictionaryLookup(buffer+at,len-2) > 0)
    {
      buffer->end = ' ';
      buffer->(end-1) = ' ';
    }

! --- suffix "es" ---
! Thanks to Max Kalus
if ((buffer->end == 's') &&
    (buffer->(end-1) == 'e') &&
    (len > 3) &&
    DictionaryLookup(buffer+at,len-2) > 0)
{
    buffer->end = ' ';
    buffer->(end-1) = ' ';
}

! --- suffix "er" ---
   if ((buffer->end == 'r') &&
        (buffer->(end-1) == 'e') &&
        (len > 3) &&
       DictionaryLookup(buffer+at,len-2) > 0)
    {
      buffer->end = ' ';
      buffer->(end-1) = ' ';
    }

! --- suffix "en" ---
   if ((buffer->end == 'n') &&
        (buffer->(end-1) == 'e') &&
        (len > 3) &&
       DictionaryLookup(buffer+at,len-2) > 0)
    {
      buffer->end = ' ';
      buffer->(end-1) = ' ';
    }

! --- suffix "em" ---	Thanks to Max Kalus
   if ((buffer->end == 'm') &&
        (buffer->(end-1) == 'e') &&
        (len > 3) &&
       DictionaryLookup(buffer+at,len-2) > 0)
    {
      buffer->end = ' ';
      buffer->(end-1) = ' ';
    }

! --- suffix "s" ---
   if ((buffer->end == 's') &&
        (len > 2) &&
        DictionaryLookup(buffer+at,len-1) > 0)
      buffer->end = ' ';

! --- suffix "n" ---
   if ((buffer->end == 'n') &&
        (len > 2) &&
        DictionaryLookup(buffer+at,len-1) > 0)
      buffer->end = ' ';

! --- suffix "e" ---
   if ((buffer->end == 'e') &&
        (len > 2) &&
        DictionaryLookup(buffer+at,len-1) > 0)
      buffer->end = ' ';

    break;
  }
}
];

#ifnot; !USE_OLD_GERMAN_SUFFIX_ROUTINE ist nicht aktiv
     
[ ProcessGermanSuffixes x at end word len i;

#ifdef TARGET_ZCODE;
for (x=0:x<parse->1:x++)
{
    word = parse-->(x*2+1);
    
    if (word == 0)                 ! if word not recognized
    {
	len = parse->(x*4+4);
	at = parse->(x*4+5);

	for(i=0:i<len:i++) buffer2->(2+i)=buffer->(at+i);
	buffer2->1 = len;
#ifnot; ! TARGET_GLULX
for (x=0:x<parse-->0:x++)
{
    word = parse-->(x*3+1);
    if (word == 0)
    {
	len = parse-->(x*3+2);
	at = parse-->(x*3+3);
	
	for(i=0:i<len:i++) buffer2->(WORDSIZE+i)=buffer->(at+i);
	buffer2-->0 = len;
#endif; ! TARGET_
	end = at+len-1;              ! last letter of the word

	PGSuffixes_helper(len,end,0);
!	break;
    }
}	
];

#ifndef GERMAN_SUFFIXES_PEDANTIC;

    !Einfacher Suffixentferner. Er entfernt alle möglichen Endungen
    !solange, bis ein bekanntes Wort entstanden ist. "Bauern" wird
    !somit zu "Bauer" und nicht zu "Bau" umgeformt. Allerdings schneidet diese
    !Version auch sinnlose Suffixes ab, wenn ein sinnvolles Wort
    !entstehen würde, z.B. würden, wenn "Bauer" bekannt ist, "Bauerssm",
    !"Bauersss" und "Bauersre" alle zu "Bauer" transformiert.
    
Array _PGS_Array ->
    !Startindex
    3 9 13
    !Round 0
    'e' 'm' 'n' 'r' 's' 0
    !Round 1
    'e' 'r' 's' 0
    !Round 2
    'e' 's' 0;

[PGSuffixes_helper len end  round   i;
    ! evtl. gar kein Längencheck?
    if (len<2)
	rfalse;

#ifdef TARGET_ZCODE;
	buffer2->1 = len;
    	Tokenise__(buffer2,parse2);
#ifnot; !TARGET_GLULX
        buffer2-->0 = len;
	Tokenise__(buffer2,parse2);
#endif; !TARGET_
    
    if (parse2-->1) !Wort bekannt
	rtrue;

    if (round>2)
	rfalse;
    
    for (i=_PGS_Array->round:_PGS_Array->i:i++) {
    	if (buffer->end == _PGS_Array->i &&
	    PGSuffixes_helper(len-1,end-1,round+1)) {
	    buffer->end = ' ';
	    rtrue;
	}
    }
    rfalse;
];

#ifnot; !GERMAN_SUFFIXES_PEDANTIC ist an

!Eine einfache Turingmaschine(ok, die andere Version könnte man auch
!als eine Bezeichnen) zum Abschneiden der Endungen. Arbeitet wie die einfache Version,
!nur schneidet sie nur "richtige" Endungen ab, z.B. nur "ern","ses" aber nicht "ssm", "sre" etc. 

Array _PGS_Array ->
!Startindex der einzelnen Zustände
    5 16 19 24 27
!Format: Zeichen, Zielzustand (99=stop); 0 schließt Liste ab
!State 0
    'e' 1 'n' 2 's' 3 'm' 4 'r' 4 0
!State 1
    's' 99 0 
!State 2
    'e' 99 'r' 4 0
!State 3
    'e' 1 0
!State 4, hier muß eines der angegeben Zeichen folgen
    'e' 99 0;

[PGSuffixes_helper len end state    i;
    
!Ist der Längencheck notwendig? Ich glaube nicht...
    if (len<2)
	rfalse;
    
    if (state ~= 4) !Spezialfall
    {
#ifdef TARGET_ZCODE;
	buffer2->1 = len;
    	Tokenise__(buffer2,parse2);
#ifnot; !TARGET_GLULX
	buffer2-->0 = len;
	Tokenise__(buffer2,parse2);
#endif; !TARGET_
	if (parse2-->1) 
	    rtrue;
    }
    
    if (state == 99)
	!Kein bekanntes Wort nach abschneiden eines Suffixes -> nicht abschneiden!
	rfalse;

    !Andere Möglichkeiten abprüfen
    for(i=_PGS_Array->state:_PGS_Array->i:i=i+2) {
	if (buffer->end == _PGS_Array->i &&
	    PGSuffixes_helper(len-1,end-1,_PGS_Array->(i+1))) {
	    buffer->end = ' ';
	    rtrue;
	}
    }
    rfalse;
];

#endif; !GERMAN_SUFFIXES_PEDANTIC

#endif; !USE_OLD_GERMAN_SUFFIX_ROUTINE

#ifdef DEBUG;
[ ShowGermanDebug x;
! 5. (optional) show all words (from italian.h by Ilario Nardinocchi)

 if (ParserTrace > 0) {
    print "[LanguageToInformese: ~";
#ifdef TARGET_ZCODE;
    for (x = 2: x < 2 + buffer->1: x++) {
#ifnot; ! TARGET_GLULX
    for (x = WORDSIZE: x < WORDSIZE + buffer-->0: x++) {
#endif; ! TARGET_
      print (char) buffer->x;
    }
    print "~]^";
    if (ParserTrace > 1) {
      print "[";
#ifdef TARGET_ZCODE;
    for (x = 2: x < 2 + buffer->1: x++) {
#ifnot; ! TARGET_GLULX
    for (x = WORDSIZE: x < WORDSIZE + buffer-->0: x++) {
#endif; ! TARGET_
        print buffer->x,",";
      }
      print "]^";
    }
 }
];
#endif;

! ---------------------------------------------------------------------------
!   Part IV.   Printing
! ---------------------------------------------------------------------------

Constant LanguageAnimateGender   = male;
Constant LanguageInanimateGender = neuter;

Constant LanguageContractionForms = 1;     ! There is no distinction in
                                           ! German



[ LanguageContraction;  return 0;
];

Array LanguageArticles -->

 !   Contraction form 0:    
 !   Cdef   Def    Indef  

     "Der " "der " "ein "           ! 0 masc sing
     "Die " "die " "eine "          ! 1 fem sing
     "Das " "das " "ein "           ! 2 neutr sing
     "Die " "die " ""               ! 3 masc plur
     "Die " "die " ""               ! 4 fem plur
     "Die " "die " "";              ! 5 neutr plur
 
                   !             a           i
                   !             s     p     s     p
                   !             m f n m f n m f n m f n                 

Array LanguageGNAsToArticles --> 0 1 2 3 4 5 0 1 2 3 4 5;

[ LanguageDirection d;
   switch(d)
   {   n_to: print "nördlich";
       s_to: print "südlich";
       e_to: print "östlich";
       w_to: print "westlich";
       ne_to: print "nordöstlich";
       nw_to: print "nordwestlich";
       se_to: print "südöstlich";
       sw_to: print "südwestlich";
       u_to: print "rauf";
       d_to: print "runter";
       in_to: print "rein";
       out_to: print "raus";
       default: return RunTimeError(9,d);
   }
];

[ LanguageNumber n f;
  if (n==0)    { print "null"; rfalse; }
  if (n<0)     { print "minus "; n=-n; }
  if (n>=1000) { print (LanguageNumber) n/1000, "tausend"; n=n%1000; f=1; }
  if (n>=100)  { if (f==1) ;
                 print (LanguageNumber) n/100, "hundert"; n=n%100; f=1; }
  if (n==0) rfalse;
!  if (f==1) print "und";  ! oblique
  switch(n)
  {   1:  print "ein";
      2:  print "zwei";
      3:  print "drei";
      4:  print "vier";
      5:  print "fünf";
      6:  print "sechs";
      7:  print "sieben";
      8:  print "acht";
      9:  print "neun";
      10: print "zehn";
      11: print "elf";
      12: print "zwölf";
      13: print "dreizehn";
      14: print "vierzehn";
      15: print "fünfzehn";
      16: print "sechzehn";
      17: print "siebzehn";
      18: print "achtzehn";
      19: print "neunzehn";
      20 to 99:
          if (n%10 ~= 0) print (LanguageNumber) n%10, "und";
          switch(n/10)
          {  2: print "zwanzig";
             3: print "dreißig";
             4: print "vierzig";
             5: print "fünfzig";
             6: print "sechzig";
             7: print "siebzig";
             8: print "achtzig";
             9: print "neunzig";
          }

  }
];

[ LanguageTimeOfDay hours mins i;
   i=hours%24;
   if (i==0) i=24;
   if (i<10) print " ";
   print i, ":", mins/10, mins%10;
   print " Uhr";
];

[ LanguageVerb i;
   if (i==#n$l)        { print "schau";              rtrue; }
   if (i==#n$z)        { print "warte";              rtrue; }
   if (i==#n$x)        { print "betrachte";           rtrue; }
   if (i==#n$i or 'inv' or 'inventory')
                       { print "inventar";         rtrue; }
   rfalse;
];


Constant NKEY__TX     = "N = nächstes";
Constant PKEY__TX     = "V = voriges";
Constant QKEY1__TX    = "     Z = zurück";
Constant QKEY2__TX    = "     Z = zurück";
Constant RKEY__TX     = "EINGABE = Artikel lesen";

Constant NKEY1__KY    = 'N';
Constant NKEY2__KY    = 'n';
Constant PKEY1__KY    = 'V';
Constant PKEY2__KY    = 'v';
Constant QKEY1__KY    = 'Z';
Constant QKEY2__KY    = 'z';

Constant SCORE__TX    = "Punkte: ";
Constant MOVES__TX    = "Züge: ";
Constant TIME__TX     = "Zeit: ";
Constant CANTGO__TX   = "Kein Weg in dieser Richtung.";
Constant FORMER__TX   = "dein früheres ich";
Constant YOURSELF__TX = "du selbst";
Constant DARKNESS__TX = "Dunkelheit";

Constant THOSET__TX   = "diese Dinge";
Constant THAT__TX     = "das";
Constant OR__TX       = " oder ";
Constant NOTHING__TX  = "nichts";
Constant IS__TX       = " ist";
Constant ARE__TX      = " sind";
Constant IS2__TX      = "siehst du ";
Constant ARE2__TX     = "siehst du ";
Constant AND__TX      = " und ";
Constant WHOM__TX     = "";
Constant WHICH__TX    = "";

! some of the following routines are replaced in TGerman.h

![ ThatorThose obj; if (obj has pluralname) { print "diese"; return; }
!  if (obj has animate)
!  {   if (obj has female) { print "sie"; return; }
!      else if (obj hasnt neuter) { print "er"; return; }
!  }
!  print "das";
!];
![ ItorThem obj;
!  if (obj has pluralname) { print "sie"; return; }
!  if (obj has animate)
!  {   if (obj has female) { print "ihr"; return; }
!      else if (obj hasnt neuter) { print "ihm"; return; }
!  }
!  print "es";
!];

[ IsorAre obj; if (obj has pluralname) print "sind"; else print "ist";
];

![ CThatorThose obj; if (obj has pluralname) print "Diese";
!  if (obj has animate)
!  {   if (obj has female) { print "Sie"; return; }
!      else if (obj hasnt neuter) { print "Er"; return; }
!  }
!  print "Dieser";
!];

![ GEristSiesind obj; if (obj has pluralname) print "Sie sind";
!  if (obj has animate)
!  {   if (obj has female) { print "Sie ist"; return; }
!      else if (obj hasnt neuter) { print "Er ist"; return; }
!  }
!  print "Dies ist";
!];

Object DunkelObj "Gegenstand"
	with dekl 1, adj "undefinierbar" "dunkl",
!Property suffixes muß noch deklariert werden.
!Also machen wir das doch hier.
    	suffixes,
	has male scenery;

[ LanguageLM n x1 flag;
	if (location == thedark) x1 = DunkelObj;
  Prompt:  print "^>";
  Miscellany:
           switch(n)
           {   1: "(Nur die ersten sechzehn Objekte werden beachtet)^";
               2: "Nichts zu tun!";
               3: print " Du bist gestorben ";
               4: print " Du hast gewonnen ";
               5: print "^Möchtest du einen NEUSTART, ein vorher 
                          gespeichertes Spiel LADEN";
                  if (TASKS_PROVIDED==0)
                      print ", die VOLLE Punktzahl des Spiels sehen";
                  if (deadflag==2 && AMUSING_PROVIDED==0)
                      print ", einige Vorschläge sehen für LUSTIGE 
                      Sachen";
                  if (DEATH_MENTION_UNDO==0)
                      print ", den letzten Zug RÜCKGÄNGIG machen";
                  " oder das ENDE?";
               6: "[Dein Interpreter kennt kein ~rückgängig~.  Tut mir leid!]";
#ifdef TARGET_ZCODE;
               7: "[Der letzte Zug konnte nicht ~rückgängig~ gemacht werden.
               		Nicht alle Interpreter haben diese Funktion.]";
#ifnot; ! TARGET_GLULX
               7: "[Du kannst nichts mehr ~rückgängig~ machen.]";
#endif; ! TARGET_
               8: "Bitte gib eine der obigen Antworten.";
               9: "^Es ist jetzt stockdunkel hier!";
              10: "Wie bitte?";
              11: "[Du kannst mit ~rückgängig~ nichts ungeschehen machen, was
                    du gar nicht getan hast!]";
              12: "[~Rückgängig~ ist nicht zweimal nacheinander möglich. Tut mir
                    leid!]";
              13: "[Letzten Zug ungeschehen gemacht.]";
              14: "[Entschuldigung, das kann nicht korrigiert werden.]";
              15: "[Denke einfach nichts davon.]";
              16: "[~Oops~ kann nur ein einzelnes Wort korrigieren.]";
              17: "Es ist stockdunkel, und du siehst rein gar nichts.";
              18: print "dich selbst";
              19: "Du siehst wunderschön aus, wie immer.";           
              20: "[Um einen Befehl wie ~Frosch, spring~ zu wiederholen, sag nur ~nochmal~,
                    nicht ~Frosch, nochmal~.]";
              21: "[Das kannst du wohl kaum wiederholen.]";
              22: "[Du kannst nicht mit einem Komma beginnen.]";
              23: "[Du scheinst mit jemandem sprechen zu wollen, aber ich weiss nicht, mit wem.]";
              24: "Du kannst mit ", (dem) x1, " nicht sprechen.";
              25: "[Um mit jemandem zu sprechen, versuche es mit ~person, hallo~ oder
                    so was ähnlichem.]";
               26: if (not_holding == player) "(Dazu nimmst du zuerst dich selbst)";
                  "(Dazu nimmst du zuerst ", (den) not_holding, ")";
              27: "Diesen Satz verstehe ich nicht.";
              28: print "Ich habe dich nur soweit verstanden: ";
              29: "Diese Zahl verstehe ich nicht.";
              30: "Du kannst nichts dergleichen sehen.";
              31: "Es sieht so aus, als hättest du zu wenig gesagt!";
              32: "Du trägst ", (den) x1, " nicht bei dir!";
              33: "[Mit diesem Verb kannst du nicht mehrere Objekte
                   ansprechen.]";
              34: "[Du kannst pro Zeile nur einmal mehrere Objekte
                   ansprechen.]";
              35: "Ich verstehe nicht, was mit ~", (address) pronoun_word,
                  "~ gemeint ist.";
              #ifdef R_NEU;
                  36: "Das ist nichts, worauf du dich in diesem Spiel beziehen musst.";
              #ifnot;
                  36: "Das ist nichts, worauf du dich in diesem Spiel beziehen mußt.";
              #endif;
              37: "Das kannst du nur mit belebten Objekten machen.";
              38: "Dieses Verb verstehe ich nicht.";
              39: "Ein flüchtiger Blick darauf sagt dir, ", (string) C_DASS,
                    " es sich um nichts wichtiges für das Spiel handelt.";
              40: "Im Augenblick ist ~", (address) pronoun_word,
                  "~ (", (der) pronoun_obj, ") nicht zu sehen.";
              41: "[Ich habe nicht verstanden, wie das endete.]";
              42: if (x1==0) print "Kein";
                  else print "Nur ", (number) x1;
                  print " davon ";
                  if (x1==1) print "ist"; else print "sind";
                  " ansprechbar.";
              43: "Nichts zu tun!";
              44: "Keiner der Gegenstände hier will diesem Befehl Folge leisten!";
              45: print "Wen meinst du, ";
              46: print "Was meinst du, ";
              47: "Du kannst dich damit nur auf einen einzigen Gegenstand beziehen.
                   Gib bitte an, welchen du meinst!";
              48: print "Wen willst du ansprechen?^";
              49: print "Du wolltest vermutlich folgendes: ";
                  if (actor~=player) print " ", (der) actor; print "~";
                  PrintCommand(); print "...~ - aber was, wie, womit?^";
              50: print "Dein Punktestand hat sich um ";
                  if (x1<0) {flag=0;x1=-x1;} else flag=1;
		  if (x1==1) print "einen Punkt ";
                    else print (number) (x1), " Punkte ";
                  if (flag) print "erhöht"; else 
			    print "verringert";	
              51: "(Da etwas sehr Dramatisches passiert ist, wurde deine Liste von
                   Verben gekürzt.)";
              52: "^Tippe eine Zahl von 1 bis ", x1,
                  ", 0 für eine Neuanzeige oder drücke ENTER.";
              53: "^[Bitte drücke die Leertaste.]";
              54: print "^Deine Antwort: ";
           }


  ListMiscellany:
           switch(n)
           {   1: print " (leuchtend)";
               2: print " (", (er) x1, " ", (isorare) x1,
                         " geschlossen)";
               3: print " (geschlossen und Licht spendend)";
               4: print " (", (er) x1, " ", (isorare) x1, 
                         " leer)";
               5: print " (leer und Licht spendend)";
               6: print " (", (er) x1, " ", (isorare) x1, 
                         " geschlossen und leer)";
               7: print " (geschlossen, leer und Licht spendend)";
               8: print " (leuchtend und angezogen";
               9: print " (leuchtend";
              10: print " (angezogen";
              11: print " (", (er) x1, " ", (isorare) x1, " ";
              12: print "offen";
              13: print "offen aber leer";
              14: print "geschlossen";
              15: print "geschlossen und verschlossen";
              16: print " und leer";
              17: print " (", (er) x1, " ", (isorare) x1, " leer)";
              18: print " (", (er) x1, " enthält ";
              19: print " (darauf ";
              20: print ", darauf ";
              21: print " (darin ";
              22: print ", darin ";
           }


  Pronouns: switch(n)
           {   1: print "Diese Pronomen stehen für jeweils folgenden Gegenstand";
               2: print "^~", (address) x1, "~ : ";
               3: print "^~", (address) x1, "~ : nichts";
               4: "Das Spiel kennt keinerlei Pronomen.";
           }
  Order:          print (gder) x1;
                  if (x1 has pluralname) print " haben"; else print " hat";
                  " besseres zu tun.";
  Quit:    switch(n)
           {   1: print "Bitte antworte entweder ja oder nein.";
               2: print "Möchtest Du wirklich aufhören? ";
           }
  Restart: switch(n)
           {   1: print "Bist du sicher, ", (string) C_DASS, "du einen Neustart willst? ";
               2: "Fehlgeschlagen.";
           }
#ifdef R_NEU;
  Restore: switch(n)
           {   1: "Laden eines Spielstandes misslang.";
               2: "In Ordnung.";
           }
  Save:    switch(n)
           {   1: "Das Speichern misslang.";
               2: "In Ordnung.";
           }
#ifnot;
  Restore: switch(n)
           {   1: "Laden eines Spielstandes mißlang.";
               2: "In Ordnung.";
           }
  Save:    switch(n)
           {   1: "Das Speichern mißlang.";
               2: "In Ordnung.";
           }
#endif;
  Verify:  switch(n)
           {   1: "Die Spielstanddatei wurde geprüft und ist in Ordnung.";
               2: "Es konnte nicht bestätigt werden, ", (string) C_DASS, "die 
                   Spielstanddatei in Ordnung ist. Möglicherweise ist
                   sie kaputt (es sei denn, Du spielst mit einem sehr 
                   einfachen Interpreter, welcher den Test nicht 
                   wirklich machen kann)."; 
            }
  ScriptOn: switch(n)
           {   1: "Das Transkribieren ist schon eingeschaltet.";
               2: "Ich beginne ein Transkript von";
               3: "Der Versuch, ein Transkript zu beginnen, scheiterte.";
           }
  
  ScriptOff: switch(n)
           {   1: "Das Transkribieren ist schon ausgeschaltet.";
               2: "^Ende des Transkriptes.";
               3: "Der Versuch, das Transkript zu beenden, scheiterte.";
           }
  NotifyOn:       "Punktezahlankündigung eingeschaltet.";
  NotifyOff:      "Punktezahlankündigung ausgeschaltet.";
  Places:         print "Du hast besucht: ";
  Objects: switch(n)
           {   1: "Objekte, mit denen du schon zu tun hattest:^";
               2: "Keines.";
               3: print "   (angezogen)";
               4: print "   (in der Hand gehalten)";
               5: print "   (weggegeben)";
               6: print "   (in ", (name) x1, ")";
               7: print "   (in ", (dem) x1, ")";
               8: print "   (innerhalb ", (des) x1, ")";
               9: print "   (auf ", (dem) x1, ")";
              10: print "   (verloren)";
           }
  Score:          if (deadflag) print "In diesem Spiel hast Du ";
                  else print "Du hast bisher ";
                  print score, " Punkte von ", MAX_SCORE, " möglichen gemacht, und zwar ";
                  if (turns>1) print "in ", turns, " Zügen";
                   else print "im Zug ", turns; return;
  FullScore: switch(n)
           {   1: if (deadflag) print "Der Punktestand war ";
                  else          print "Der Punktestand ist ";
                  "folgendermaßen zusammengesetzt:^";
               2: "für das Finden diverser Dinge";
               3: "für den Besuch verschiedenster Orte";
               4: print "insgesamt (von ", MAX_SCORE; ")";
           }
  Inv:     switch(n)
           {   1: "Du trägst nichts bei dir.";
               2: print "Du trägst";
           }
  Take:    switch(n)
           {   1: "Du trägst ", (den) x1, " jetzt bei dir.";
               2: "Du bist schon in deiner eigenen Hand.";
               3: print "Ich nehme nicht an, ", (string) C_DASS,(der) x1, " das ";
                  singplur(x1, "möchte", "möchten");
                  print_ret ".";
               4: print "Du solltest zuerst ";
                  if (x1 has supporter) print "von "; else print "aus ";
                  print_ret (dem) x1, " kommen.";
               5: "Du hast ", (diesen) x1, " schon.";
               6: print (GDer) noun, " ";
                  singplur(noun, "scheint", "scheinen");
                  " zu ", (dem) x1, " zu gehören.";
               7: print (GDer) noun, " ";
                  singplur(noun, "scheint", "scheinen");
                  " ein Teil von ", (dem) x1, " zu sein.";
               8: print_ret (Gdieser) x1, " ", (isorare) x1,
                  " nicht vorhanden.";
!               9: print_ret (gder) x1, " ", (isorare) x1, " nicht offen.";
		9: print_ret "Du kommst nicht an diesen Gegenstand heran, da ",
			(der) x1, " nicht offen ", (isorare) x1, ".";
              10: print_ret (gder) x1, " ", (isorare) x1, " zu schwer für dich.";
!              11: print_ret (GEristsiesind) x1, " wahrscheinlich am Boden
!                       festgenagelt... Nichts zu machen!";
              11: print_ret (GDer) x1, " ", (ist) x1," hier fest verankert.";
              12: "Du trägst schon zu viel mit dir herum.";
              13: "(Dazu legst du ", (den) x1, " in ", (den) SACK_OBJECT,
                  ", um Platz zu schaffen)";
           }
  Drop:    switch(n)
           {   1: print_ret (GEristSiesind) x1, " schon hier.";
               2: "Du hast ", (diesen) x1, " nicht.";
               3: "(Dazu nimmst du zuerst ", (den) x1, ")";
               4: "Fallengelassen.";
           }
  Remove:  switch(n)
           {   1: print_ret (GEristSiesind) x1, " unglücklicherweise geschlossen.";
               2: print_ret (GDer) x1, " befindet sich aber nicht dort!";
               3: "Entfernt.";
           }
#ifdef R_NEU;
  PutOn:   switch(n)
           {   1: "Du mußt ", (den) x1,
                  " zuerst haben, bevor du ", (ihn) x1,
                  " auf etwas anderes legen kannst.";
               2: "Du kannst nichts auf sich selbst legen.";
               3: "Dinge auf ", (den) x1, " zu legen, würde nichts bringen.";
               4: "Dir fehlt die erforderliche Geschicklichkeit.";
               5: "(Dazu nimmst du ", (ihn) x1, " zuerst)^";
               6: "Da ist kein Platz mehr auf ", (dem) x1, ".";
               7: "Gesagt, getan!";
               8: "Du legst ", (den) x1, " auf ", (den) second, ".";
           }
  Insert:  switch(n)
           {   1: "Du mußt ", (den) x1,
                  " zuerst haben, bevor du ", (ihn) x1,
                  " in etwas anderes legen kannst.";
               2: print (Gdieser) x1, " ";
                  singplur(x1, "kann", "können");
                  " keine Dinge enthalten.";
               3: print_ret (gder) x1, " ", (isorare) x1, " geschlossen.";
               4: "Du solltest ", (ihn) x1, " zuerst wegnehmen.";
               5: "Du kannst nichts in sich selbst legen.";
               6: "(Dazu nimmst du ", (ihn) x1, " zuerst)^";
               7: "Da ist kein Platz mehr in ", (dem) x1, ".";
               8: "Gesagt, getan!";
               9: "Du legst ", (den) x1, " in ", (den) second, ".";
           }
#ifnot;
  PutOn:   switch(n)
           {   1: "Du musst ", (den) x1,
                  " zuerst haben, bevor du ", (ihn) x1,
                  " auf etwas anderes legen kannst.";
               2: "Du kannst nichts auf sich selbst legen.";
               3: "Dinge auf ", (den) x1, " zu legen, würde nichts bringen.";
               4: "Dir fehlt die erforderliche Geschicklichkeit.";
               5: "(Dazu nimmst du ", (ihn) x1, " zuerst)^";
               6: "Da ist kein Platz mehr auf ", (dem) x1, ".";
               7: "Gesagt, getan!";
               8: "Du legst ", (den) x1, " auf ", (den) second, ".";
           }
  Insert:  switch(n)
           {   1: "Du musst ", (den) x1,
                  " zuerst haben, bevor du ", (ihn) x1,
                  " in etwas anderes legen kannst.";
               2: print (Gdieser) x1, " ";
                  singplur(x1, "kann", "können");
                  " keine Dinge enthalten.";
               3: print_ret (gder) x1, " ", (isorare) x1, " geschlossen.";
               4: "Du solltest ", (ihn) x1, " zuerst wegnehmen.";
               5: "Du kannst nichts in sich selbst legen.";
               6: "(Dazu nimmst du ", (ihn) x1, " zuerst)^";
               7: "Da ist kein Platz mehr in ", (dem) x1, ".";
               8: "Gesagt, getan!";
               9: "Du legst ", (den) x1, " in ", (den) second, ".";
           }
#endif;
  EmptyT:  switch(n)
           {   1: print (Gdieser) x1, " ";
                  singplur(x1, "kann", "können");
                  " keine Dinge enthalten.";
               2: print_ret (Gder) x1, " ", (isorare) x1, " geschlossen.";
               3: print_ret (Gder) x1, " ", (isorare) x1, " schon leer.";
               4: "Diese Aktion würde kaum etwas leeren.";
           }
  Give:    switch(n)
           {   1: "Du hast ", (den) x1, " nicht.";
               2: "Du wedelst eine Weile mit ", (dem) x1,
                  " herum, aber erreichst nicht viel .";
               3: print (Gder) x1, " ";
                  singplur(x1, "sieht", "sehen");
                  " nicht interessiert aus.";
           }
  Show:    switch(n)
           {   1: "Du hast ", (Gden) x1, " nicht.";
               2: print_ret (Gder) x1, " ", (isorare) x1, 
                   " nicht beeindruckt.";
           }
  Enter:   switch(n)
           {   1: print "Aber du bist schon ";
                  if (x1 has supporter) print "auf "; else print "in ";
                  print_ret (dem) x1, ".";
               2: print_ret (GEristSiesind) x1, " nichts, in das du hineingelangen
                    könntest.";
               3: "Du gelangst nicht in ", (der) x1, " weil ", (er) x1, 
                   " geschlossen ist.";
               4: "Du kannst nur in etwas hineinkommen, das frei steht.";
               5: print "Du gelangst ";
                  if (x1 has supporter) print "auf "; else print "in ";
                  print_ret (den) x1, ".";
               6: print "(Du kommst ";
                  if (x1 has supporter) print "herunter von "; 
                  else print "hinaus aus "; print (dem) x1; ")";
               7: if (x1 has supporter) "(Du gelangst auf ", (den) x1, ")^";
                  if (x1 has container) "(Du gelangst in ", (den) x1, ")^";
                  "(Du trittst in ", (den) x1, " ein)^";
           }
  GetOff:         "Aber du bist im Augenblick nicht auf ", (dem) x1, ".";
  Exit:    switch(n)
           {   1: "Aber du bist im Augenblick in nichts drin.";
               2: "Du kommst aus dem verschlossenen ", (name) x1, 
                  " nicht hinaus.";
               3: print "Du gelangst ";
                  if (x1 has supporter) print "runter von "; 
                  else print "hinaus aus "; print_ret (dem) x1, ".";
               4: !Bugfix, Inform Patches [LEAVE tries too hard]
                  print "Aber du bist doch gerade gar nicht ";
                  if (x1 has supporter) print "auf"; else print "in"; 
                  print_ret " ", (dem) x1, ".";
           }
#ifdef R_NEU;
  VagueGo: "Du solltest sagen, in welche Kompassrichtung du gehen willst.";
#ifnot;
  VagueGo: "Du solltest sagen, in welche Kompaßrichtung du gehen willst.";
#endif;

  Go:      switch(n)
           {   1: print "Du solltest zuerst ";
                  if (x1 has supporter) print "runter von "; else print "aus ";
                  print_ret (dem) x1, " kommen.";
               2: "Du kannst nicht in diese Richtung gehen.";
               3: "Du bist unfähig, auf ", (den) x1, " zu klettern.";
               4: "Du bist unfähig, ", (den) x1, " hinunterzugehen.";
               5: "Du kannst nicht, weil ", (der) x1, " geschlossen ", (isorare) x1, ".";
               6: print "Du kannst nicht weil ", (der) x1, " nirgendwohin ";
                  if (x1 has pluralname) "führt.";
                  "führen.";
           }

  LMode1:         " ist jetzt im normalen Beschreibungsmodus. Es werden ab nun lange
                    Beschreibungen von Orten gegeben, an denen du noch nie gewesen bist, und
                    kurze von Orten, die du schon besucht hast.";
  LMode2:         " ist jetzt im ausführlichen Beschreibungsmodus. Es werden ab nun
                    immer lange Beschreibungen von Orten gegeben (selbst wenn du schon einmal
                    dort warst)."; 
  LMode3:         " ist jetzt im superkurzen Beschreibungsmodus. Es werden nun immer
                    kurze Beschreibungen von Orten gegeben (selbst wenn du vorher noch nie
                    dort warst).";

  Look:    switch(n)
           {   1: print " (auf ", (dem) x1, ")";
               2: print " (in ", (dem) x1, ")";
 !               3: print " (als "; @print_obj x1; print ")";
               3: print " (als ", (object) x1, ")";
               4: print "^Auf ", (dem) x1;
                  WriteListFromCase(child(x1),
                      ENGLISH_BIT + RECURSE_BIT + PARTINV_BIT
                      + TERSE_BIT + ISARE_BIT + CONCEAL_BIT, 0, Nom);
                  ".";
         default: if (x1~=location)
                  {   if (x1 has supporter) print "^Auf "; else print "^In ";
                      print (dem) x1, " siehst du hier ";
                  }
                  else print "^Du siehst hier ";
                  if (n==5) print "auch ";
                  WriteListFrom(child(x1),
                      ENGLISH_BIT + WORKFLAG_BIT + RECURSE_BIT
                      + PARTINV_BIT + TERSE_BIT + CONCEAL_BIT);
                  if (x1~=location) ".";
                  ".";
           }

  Examine: switch(n)
           {   1: "Dunkelheit, die. Abwesenheit von Licht.";
               2: if (x1 == u_obj or d_obj) "Dort ", (name) x1, " entdeckst du nichts Spezielles.";
                  print "Du entdeckst ";
                  if (x1 ofclass CompassDirection) print "im ", (name) x1;
               	  else print "an ", (dem) x1;
               	  " nichts Spezielles.";
               3: print (Gder) x1, " ", (isorare) x1, " momentan ";
                  if (x1 has on) "eingeschaltet."; else "ausgeschaltet.";
           }
  LookUnder: switch(n)
           {   1: "Aber es ist dunkel.";
               2: "Du findest nichts Interessantes.";
           }

  Search:  switch(n)
           {   1: "Aber es ist dunkel.";
               2: "Da ist nichts auf ", (dem) x1, ".";
               3: print "Auf ", (dem) x1;			!Max Kalus
                  WriteListFromCase(child(x1),
                      TERSE_BIT + ENGLISH_BIT + ISARE_BIT + CONCEAL_BIT, 0, Gen);
                  ".";
               4: "Du findest nichts Interessantes.";
               5: "Du kannst in ", (dem) x1, " nichts sehen, weil ", 
                    (er) x1, " geschlossen ", (isorare) x1, ".";
               6: print_ret (Gder) x1, " ", (isorare) x1, " leer.";
               7: print "In ", (dem) x1, " siehst du ";
                  WriteListFrom(child(x1),
                      TERSE_BIT + ENGLISH_BIT + CONCEAL_BIT);
                  ".";
           }

#ifdef R_NEU;
  Unlock:  switch(n)
           {   1: print (GDer) x1, " s";
                  if (x1 has pluralname) print "ehen";
                  else print "ieht";
                  " nicht aus wie etwas, das du aufschließen könntest.";
               2: print_ret (GEristSiesind) x1,
                  " ist im Augenblick aufgeschlossen.";
               3: print (GDer) x1, " sch";
                  if (x1 has pluralname) print "einen";
                  else print "eint";
                  " nicht ins Schloss zu passen.";
               4: "Du schließt ", (den) x1, " auf.";
           }
  Lock:    switch(n)
           {   1: print (GDer) x1, " s";
                  if (x1 has pluralname) print "ehen";
                  else print "ieht";
                  " nicht aus wie etwas, das du abschließen könntest.";
               2: print_ret (GEristSiesind) x1, " im Augenblick verschlossen.";
               3: "Zuerst solltest du ", (den) x1, " schließen.";
               4: print (GDer) noun, " sch";
                  if (noun has pluralname) print "einen";
                  else print "eint";
                  " nicht ins Schloss zu passen.";
               5: "Du verschließt ", (den) x1, ".";
           }
#ifnot;
  Unlock:  switch(n)
           {   1: print (GDer) x1, " s";
                  if (x1 has pluralname) print "ehen";
                  else print "ieht";
                  " nicht aus wie etwas, das du aufschließen könntest.";
               2: print_ret (GEristSiesind) x1,
                  " ist im Augenblick aufgeschlossen.";
               3: print (GDer) x1, " sch";
                  if (x1 has pluralname) print "einen";
                  else print "eint";
                  " nicht ins Schloß zu passen.";
               4: "Du schließt ", (den) x1, " auf.";
           }
  Lock:    switch(n)
           {   1: print (GDer) x1, " s";
                  if (x1 has pluralname) print "ehen";
                  else print "ieht";
                  " nicht aus wie etwas, das du abschließen könntest.";
               2: print_ret (GEristSiesind) x1, " im Augenblick verschlossen.";
               3: "Zuerst solltest du ", (den) x1, " schließen.";
               4: print (GDer) noun, " sch";
                  if (noun has pluralname) print "einen";
                  else print "eint";
                  " nicht ins Schloß zu passen.";
               5: "Du verschließt ", (den) x1, ".";
           }
#endif;

  SwitchOn: switch(n)
           {   1: print_ret (Gden) x1,
                  " kannst du weder ein- noch ausschalten.";
               2: print_ret (GEristSiesind) x1,
                  " schon eingeschaltet.";
               3: "Du schaltest ", (den) x1, " ein.";
           }
  SwitchOff: switch(n)
           {   1: print_ret (Gden) x1,
                  " kannst du weder aus- noch einschalten.";
               2: print_ret (GEristSiesind) x1,
                  " schon ausgeschaltet.";
               3: "Du schaltest ", (den) x1, " aus.";
           }

  Open:    switch(n)
           {   1: print_ret "Man kann ", (den) x1, " nicht öffnen.";
               2: print_ret (GDer) noun, " schein", (endT) noun, " verschlossen zu sein.";
               3: print_ret (GEristSiesind) x1,
                  " schon offen.";
               4: print "Du öffnest ", (den) x1, " und bringst ";
                  if (child(x1)==0) print "nichts";
                  else if (WriteListFrom(child(x1),
                      ENGLISH_BIT + TERSE_BIT + CONCEAL_BIT)==0) 
                       "nichts";
                  " zum Vorschein.";
               5: "Du öffnest ", (den) x1, ".";
           }

  Close:   switch(n)
           {   1: print_ret (GDen) x1,
                  " kannst du nicht schließen.";
               2: print_ret (GEristSiesind) x1,
                  " schon geschlossen.";
               3: "Du schließt ", (den) x1, ".";
           }
  Disrobe: switch(n)
           {   1: "Du trägst ", (ihn) x1, " nicht.";
               2: "Du ziehst ", (den) x1, " aus.";
           }
  Wear:    switch(n)
           {   1: "Du kannst ", (diesen) x1, " nicht anziehen!";
               2: "Du hast ", (diesen) x1, " nicht!";
               3: "Du hast ", (diesen) x1, " schon angezogen!";
               4: "Du ziehst ", (den) x1, " an.";
           }
#ifdef R_NEU;
  Eat:     switch(n)
           {   1: print_ret (GEristSiesind) x1,
                  " völlig ungenießbar.";
               2: "Du isst ", (den) x1, ". Nicht schlecht.";
           }
#ifnot;
  Eat:     switch(n)
           {   1: print_ret (GEristSiesind) x1,
                  " völlig ungenießbar.";
               2: "Du ißt ", (den) x1, ". Nicht schlecht.";
           }
#endif;

  Yes, No:        "Das war eine rhetorische Frage.";
  Burn:           "Diese gefährliche Aktion würde wenig bringen.";
  Pray:           "Dein Gebet bringt dir in praktischer Hinsicht nichts.";
  Wake:           "Die schreckliche Wahrheit lautet: Das hier ist kein Traum.";
  WakeOther:      "Das scheint unnötig zu sein.";
  Kiss:           "Konzentriere dich auf das Spiel.";
  Think:          "Was für eine gute Idee!";
  Smell:          "Du riechst nichts Unerwartetes.";
  Listen:         "Du hörst nichts Unerwartetes.";
  Taste:          "Du schmeckst nichts Unerwartetes.";
  Touch:   switch(n)
           {   1: "Behalte deine Hände bei dir!";
               2: "Du fühlst nichts Unerwartetes.";
               3: "Wenn du denkst, ", (string) C_DASS, "es vielleicht hilft.";
           }
  Dig:            "Graben würde hier nichts bringen.";
  Cut:            "Das Schneiden gestaltet sich ohne Werkzeug schwierig.";
  Jump:           "Du hüpfst an Ort und Stelle. Ohne ersichtlichen Erfolg.";
  JumpOver, Tie:  "Damit würdest du nichts erreichen.";
  Drink:          "Es ist nichts Trinkbares in der Nähe.";
  Fill:           "Aber es gibt hier kein Wasser.";
  Sorry:          "Oh, macht nichts.";
  Strong:         "Echte Abenteurer sprechen diese Sprache nicht.";
  Mild:           "Ziemlich.";
  Attack:         "Gewalt ist keine Antwort!";
  Swim:           "Hier gibt es nicht genug Wasser, um zu schwimmen.";
  Swing:          "Hier gibt es nichts, was schwingen könnte.";
  Blow:           "Du kannst ", (diesen) x1, " nicht sinnvoll blasen.";
  Rub:            "Damit erreichst du nichts.";
  Set:            "Nein, du kannst ", (diesen) x1, " nicht einstellen.";
  SetTo:          "Nein, du kannst ", (diesen) x1, 
                    " auf nichts einstellen.";
  WaveHands:      "Du winkst und fühlst dich lächerlich.";
  Wave:    switch(n)
           {   1: "Du hast ", (diesen) x1, " nicht.";
               2: "Du siehst lächerlich aus wie du ", (den) x1, " wedelst.";
           }
  Pull, Push, Turn:
           switch(n)
           {   1: print_ret (GEr) x1, " beweg", (endT) x1,
                  " sich keinen Millimeter.";
               2: "Du bist dazu unfähig.";
               3: "Offenbar passiert nichts.";
               4: "Das wäre nicht besonders höflich.";
           }
  PushDir: switch(n)
           {   1: "Ist das das beste, was dir einfällt?";
               2: "Das ist keine Richtung.";
               3: "In diese Richtung geht das nicht.";
           }
  Squeeze: switch(n)
           {   1: "Behalte deine Hände bei dir.";
               2: "Damit erreichst du nichts.";
           }
  ThrowAt: switch(n)
           {   1: "Idiotisch.";
               2: "Du hast im entscheidenden Moment nicht die Nerven dazu.";
           }
  Tell:    switch(n)
           {   1: "Du führst eine Weile lang Selbstgespräche.";
               2: "Das scheint keine Reaktion zu provozieren.";
           }
  Answer, Ask:    "Es kommt keine Antwort.";
  Buy:            "Es gibt nichts zu kaufen.";
  Sing:           "Dein Gesang ist abscheulich.";
  Climb:          "Ich denke nicht, ", (string) C_DASS, "damit viel erreicht werden könnte.";
  Wait:           "Zeit geht vorbei.";
  Sleep:          "Du fühlst dich nicht besonders schläfrig.";
  Consult:        "In ", (dem) x1, " steht darüber nichts Interessantes.";
];

! ---------------------------------------------------------------------------
