! Eine Library für Choose Your Own Adventure- bzw. Multiple-Choice-Spiele
! getestet mit Inform 6.21 unter Windows 2000.
! Diese Datei muss nach den Objekten eingebunden werden.

[Play key real;
  do {
    SetOptions();
    PrintOptions();
    new_line;
    print ">";
    @read_char 1 -> key;
    if (33>key)  print "*^^"; else {
      if (key>126) print "*^^"; else {
        print (char) key, "^^";  ! Nicht den Wert, sondern das dahinterliegende Zeichen
      };
    };
    switch (key) {           ! Achtung! Key ist der ZSCII-Wert des Buchstabens
      72, 104:  ! H(elp), H(ilfe)
                print "In diesem Spiel musst du nur die Ziffer deiner Wahl eingeben,
                      um Entscheidungen zu treffen. Vor jedem Zug wird angezeigt,
                      welche Zahl für welche Option steht. Außer den Zahlen von 1 bis 9
                      sind folgende Eingaben möglich:^^";
                      spaces 3; style bold; print"H";
                      style roman; print " ruft diesen Hilfstext auf,^";
                      spaces 3; style bold; print"L";
                      style roman; print " zeigt die momentane Lage noch einmal an,^";
                      spaces 3; style bold; print"S";
                      style roman; print " speichert den aktuellen Spielstand,^";
                      spaces 3; style bold; print"W";
                      style roman; print " kann einen gespeicherten Spielstand wiederherstellen, und^";
                      spaces 3; style bold; print"E";
                      style roman; print " beendet das Spiel.^^Im
                      Augenblick stehen folgende Ziffern zur Auswahl:^^";
      48:       print "Bitte gib eine Nummer zwischen 1 und ", nr_valid_options, " ein.^^";
      ! 0
      49 to 57: key=key-48;  ! Hier wird in "echte" Zahlen umgerechnet
      ! 1 - 9
                if (key>nr_valid_options) {
                  print "Bitte gib eine Ziffer zwischen 1 und ", nr_valid_options, " ein.^^";
                }
                else {
                  real = valid_options->key;
                  current_room.exec(real);
                };
      76, 108:  print (string) current_room.text;
      ! L(age), L(ook)
      101, 69:  game_over=true;
      ! E(nd), E(nde)
      83,115:   SaveGame();
      ! S(ave), S(peichern)
      82, 87, 114, 119:
      ! R(estore), W(iederherstellen)
                RestoreGame();
      13,32:    print "Nanu?^^";
      ! Leertaste oder Return
      default:  print "Wie bitte?^^";
    };
  }
  until (game_over);         ! Das Ausdrucken einer Nachricht bleibt dem Objektproperty überlassen
];                           ! CYOA unterscheidet nicht zwischen Gewonnen und Verloren


[SaveGame;
  save saved;
  "Speichern nicht möglich.^";
  .saved;
  "O.K.^";
];

[RestoreGame;
  restore restored;
  "Wiederherstellen nicht möglich.^";
  .restored;
  "O.K.^";
];

[ClearOptions i;
  ! Setze die Werte-Zuordnung auf Null
  for (i=1:i<=valid_options->0:i++) {
    valid_options->i = 0;
  };
];


[SetOptions displayed maxoption real;    ! Reale und angezeigte Nummern müssen zugeordnet werden
  ClearOptions();                        ! Erst alles löschen
  maxoption = current_room.#option/2;
  real = 0;
  for (displayed=1:displayed<=maxoption:displayed++) {
      do {
        if (real <= maxoption) {
            if (current_room.&active-->real == 1) {
              valid_options->displayed = real;
              nr_valid_options = displayed;
              real++;
              break;
            }
            else real++;
        };
      }
      until (real>maxoption);
  };
];


[PrintOptions i real;
  for (i=1:i<=nr_valid_options:i++) {
    real = valid_options->i;
    print "   ", i, ": ";
    print (string) current_room.&option-->real;
    new_line;
  };
];

[set i j;
  if (j == 0) j = current_room;
  if (i > current_room.#option/2) {
     print "[*** Programmierfehler: Option ", i, " von Objekt ";
     print current_room, " konnte nicht aktiviert werden. Das Objekt ";
     print "hat nur ", current_room.#option/2, " Optionen! ***}]^^";
  };
  j.&active-->i = 1;
];

[unset i j;
  if (j == 0) j = current_room;
  if (i > current_room.#option/2) {
     print "[*** Programmierfehler: Option ", i, " von Objekt ";
     print current_room, " konnte nicht deaktiviert werden. Das Objekt ";
     print "hat nur ", current_room.#option/2, " Optionen! ***]^^";
  };
  j.&active-->i = 0;
];

[goto i;
      current_room=i;
      print (string) current_room.text;
];

[Main;
  Init();
  Play();
  print "Auf Wiedersehen!^^";
];
