Forum moved to if-forum.org
Autor Nachricht
<  Tot oder nicht tot, das ist hier die Frage...
Clive
BeitragVerfasst am: Di, 22 Jul 2003 - 9:17  Antworten mit Zitat
Wasserträger
Wasserträger


Anmeldungsdatum: 29.08.2002
Beiträge: 60

So, nach relativ langer Zeit melde ich mich auch mal wieder. Natürlich aufgrund eines Problems. :roll:

Es geht darum, dass ich NPCs brauche, die mal tot und mal nicht sind. Bisher muss ich noch bei jedem Objekt die Routinen für die Todesnachrichten extra einfügen, weil das mit der Klasse nicht funktionieren wollte.
Beispiel:

Code:

Object Gardist "Gardist"
     with   name 'gardist' 'soldat',
   dekl 3,
   description [; if (self hasnt dead) "Grimmig erwidert der Gardist deine Blicke.";ddesc();rtrue; ],
   life [; Ask, Answer, Tell: if (self hasnt dead) "Er ist nicht zum Sprechen aufgelegt.";dtalk();rtrue; ],
   before [;
        Touch: if (self hasnt dead) "~Lass deine dreckigen Finger von mir!~, knurrt er dich an.
      Du beschließt, seiner Aufforderung besser nachzukommen.";dtouch();rtrue;
        Take, Push, Pull, Remove, Turn:
      if (self hasnt dead)
      "Ein warnendes Aufblitzen in den Augen des Soldaten überzeugt dich,
      es besser nicht zu versuchen.";dget();rtrue;
        Attack: if (self hasnt dead) "Im Kampf Mann-zu-Mann bist du ihm nicht gewachsen.";
      dattack();rtrue;
        ],
     has   male animate;


Weiß jemand eine bessere Möglichkeit, die auf mehrere Objekte übertragbar ist? So ist es nämlich ziemlich umständlich. Mit einer Klasse für die Toten habe ich es schon probiert, aber anstelle des Alternativtextes wurde dann gar nichts ausgegeben, sobald das Objekt das Attribut dead bekommen hatte(bzw. nur die standardnachrichten der library).


Mein zweites Problem ist das Adjektiv. Wenn da steht:
"Du siehst hier einen Gardist."
obwohl der Gardist tot ist, erscheint mir das etwas verwirrend, vor allem, wenn er in einem Satz mit anderen NPCs genannt wird, die noch leben.
Ich habe allerdings nicht geschafft, nachträglich ein Adjektiv einzufügen. Wenn ich es auf ähnliche Weise wie oben versuche, wird ausgegeben:
"Du siehst hier einen yten Gardist."
oder ein Buchstabensalat, wenn ich es mittels Object.adj und Routine versuche.
Woran liegt das und wie kann ich es umgehen?
Eine Alternative wäre natürlich die initial - property, aber das ist dann wieder ein Haufen Mehrarbeit, vor allem, wenn es viele verschiedene Tote im Spiel gibt. 8)
Außerdem hätte ich (wenn möglich) schon gern wechselnde Adjektive...


Vielen Dank im Vorraus schonmal für hoffentlich viele fachkundige Antworten. :wink:
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Sophie
BeitragVerfasst am: Mi, 23 Jul 2003 - 13:21  Antworten mit Zitat
Gast





Hi,

es ist ein bisschen schwierig, zu sagen, was du falsch machst, weil du zu wenig Code gezeigt hast.

Ich hab da was zusammengebastelt, das ist ein bisschen lang, aber es scheint mehr oder weniger zu funktionieren. Allerdings hab ich eine uralte deutsche Library gehabt, und weiss nicht, wie das bei neueren ist.

Code:
Constant Story "Spass mit Gardisten";
Constant Headline "^Interaktive tote Gardisten^Jetzt leben sie noch. Um einen von ihnen^umzubringen, sing, spring oder warte.^";

Attribute dead;

Include "Parser";

! Das brauch ich, weil ich nicht weiss, wie ich die Gardisten sonst
! umbringen soll
Object LibraryMessages
  with before [;
    Sing:
      if (gardist1 hasnt dead) {
        gardist1.die();
        "Ein greller Ton schneidet durch die Luft. Ein Gardist fällt tot um.";
      }
    Jump:
      if (gardist2 hasnt dead) {
        gardist2.die();
        "Oops, aus Versehen springst du auf einen Gardisten. Er ist sofort tot.";
      }
    Wait:
      if (gardist3 hasnt dead) {
        gardist3.die();
        "Die Zeit vergeht...^^Wumpf! Ein Gardist ist umgefallen. Er ist an einer
        Überdosis Zeit gestorben.";
      }
  ];

Include "VerbLib";

Object here "Hier"
  with description "In der Gardisterei sind Gardisten.",
  has light;

Class Gardist
 with name 'gardist' 'soldat' 'toten',
   dekl 3,
   short_name [;
     self.nummer();
     print "Gardist";
     if (self has dead) print ", der tot ist";
     rtrue;
   ],
   die [; give self dead; ],
   description [;
     if (self hasnt dead)
       "Grimmig erwidert der Gardist deine Blicke.";
     ddesc(); rtrue;
   ],
   life [;
     Ask, Answer, Tell:
       if (self hasnt dead)
         "Er ist nicht zum Sprechen aufgelegt.";
       dtalk(); rtrue;
   ],
 before [;
     Touch:
       if (self hasnt dead)
         "~Lass deine dreckigen Finger von mir!~, knurrt er dich an. Du beschließt,
         seiner Aufforderung besser nachzukommen.";
       dtouch(); rtrue;
     Take, Push, Pull, Remove, Turn:
       if (self hasnt dead)
         "Ein warnendes Aufblitzen in den Augen des Soldaten überzeugt dich, es
         besser nicht zu versuchen.";
       dget(); rtrue;
     Attack:
       if (self hasnt dead) "Im Kampf Mann-zu-Mann bist du ihm nicht gewachsen.";
       dattack(); rtrue;
   ],
  has male animate;

 Gardist gardist1 here
  with nummer [; print "ersten "; ],
    name 'ersten';
Gardist gardist2 here
  with nummer [; print "zweiten "; ],
    name 'zweiten';
Gardist gardist3 here
  with nummer [; print "dritten "; ],
    name 'dritten';

[ ddesc; "Er liegt tot herum."; ];
[ dtalk; "Er sagt nichts, weil Tote reden normalerweise nicht."; ];
[ dtouch; "Er fühlt sich tot an."; ];
[ dget; "Er ist zu schwer."; ];
[ dattack; "Du kickst den Toten in die Rippen. Cool!"; ];

[ Initialise;
  location = here;
  "^^Und hopp, in die Gardisterei...^^";
];

Include "Germang";


Ich hoffe, du kannst was damit anfangen.

(Außerdem hoff ich, dass das so ausschaut, wie es soll, hab noch nie hier gepostet.)

Sophie
Nach oben
Clive
BeitragVerfasst am: Mi, 23 Jul 2003 - 21:31  Antworten mit Zitat
Wasserträger
Wasserträger


Anmeldungsdatum: 29.08.2002
Beiträge: 60

Danke!

Ja, damit kann ich etwas anfangen.
Mein ursprünglicher Fehler war, dem Gardist erst im toten Zustand seine Klasse zuzuweisen, die sich nur auf seine Todesnachrichten bezieht.
Das hatte sich zwar zwischenzeitlich erledigt, aber auf die Idee, das Adjektiv zu umschreiben, statt selbst zu benutzen, bin ich noch gar nicht gekommen. Danke vielmals, das wird mir helfen!

Das nächste Problem ist allerdings schon in Sicht. Wie in deinem Beispiel nämlich auch aufgeführt, brauche ich mehrere "Gardisten" (lassen wir sie mal weiterhin die Sündenböcke sein). Und zwar in Verbindung mit einem Kampfsystem.

Alles funktioniert perfekt, solange wir bei einem Gardisten bleiben.
Aber bei mehreren sieht es im Moment ja so aus:

Code:

>l
Du siehst hier einen Gardist, einen Gardist und einen Gardist.

>toete gardist
Ein Gardist stirbt.

>l
Du siehst hier einen Gardist, einen Gardist und einen Gardist, der tot ist.


etc.

Was ich erreichen will, ist allerdings:

Code:

>l
Du siehst hier drei Gardisten.

>toete gardist
Ein Gardist stirbt.

>l
Du siehst hier zwei Gardisten und einen Gardist, der tot ist.

>toete Gardist
Ein Gardist stirbt.

>l
Du siehst hier einen Gardist und zwei Gardisten, die tot sind.


Ich bin sicher, es gibt eine entsprechende Stelle im Manual, aber irgendwie hab ich das Richtige noch nicht gefunden, da sie sich auch unabhängig voneinander bewegen können müssen.
Wenn z.B. der Spieler in eine Stadt kommt, und die Gardisten die Stadtwache darstellen, von denen hier und da einige sind und die Zahlen auch wechseln.

Jemand ne Idee? Verweis auf Seite im Manual? Oder wäre das eine passende Aufgabe für den Guru-Wettbewerb?

Vielen Dank schonmal für alle Antworten!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Clive
BeitragVerfasst am: Sa, 2 Aug 2003 - 13:49  Antworten mit Zitat
Wasserträger
Wasserträger


Anmeldungsdatum: 29.08.2002
Beiträge: 60

Wirklich niemand ne Idee?

Im Moment kann ich die Gardisten nur zusammenlegen, wenn sie unangreifbar sind. Denn wenn ich sie als Klasse deklariere...

Code:

attribute dead;

Class Gardist
  with name 'gardist',
          dekl 3,
          description [; if (self hasnt dead) {"Ein grimmiger Gardist.";}
                         "Ein toter Gardist."; ],
          before [; Attack: if (self hasnt dead) {
                         give self dead;
                         "Er fällt tot um.";}
                         "Er ist schon tot."; ],
  has  male animate;


und dann ein paar von ihnen in einen Raum setze...

Code:

Raum "Ein Raum"
  with description "Kahl und leer ist es hier.",
  has  light;

Gardist "Gardist" Raum;
Gardist "Gardist" Raum;
Gardist "Gardist" Raum;


Habe ich sie zwar gestapelt, aber sämtliche Aktionen beziehen sich nur auf den ersten. Bsp.:

Code:

>l
Kahl und leer ist es hier.

Du siehst hier drei Gardisten.

>b gardist
Ein grimmiger Gardist.

>toete gardist
Er fällt tot um.

>b gardist
Ein toter Gardist.

>l
Kahl und leer ist es hier.

Du siehst hier drei Gardisten.

>toete gardist
Er ist schon tot.


Man sieht also weder, dass einer von ihnen tot ist, noch kann man mit den anderen interagieren, solange der erste sich noch im Raum befindet.

Ich verzweifle noch daran!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Sophie
BeitragVerfasst am: Mo, 4 Aug 2003 - 12:47  Antworten mit Zitat
Gast





Ich hab mir das jetzt genauer angeschaut. Ich glaube, es geht
nicht, dass man das automatisch auflisten lässt, und trotzdem
die Gardisten unterscheiden kann. Am Einfachsten wäre es
wahrscheinlich, wenn du die Aufzählung selbst codierst, mit
einer describe property in der Klassendefinition. (Nicht, dass ich
das ausprobiert hätte.)

Z.B. du zählst, wieviele Gardisten im Raum sind, und wieviele
davon tot sind, und schreibst das dann selbst. Ungefähr so:

Code:

describe [ i x y;
  objectloop (i in location && i ofclass Gardist) {
    if (i has dead) y++;
    else x++;
  }
  "^Im Raum sind ", (wie auch immer man Zahlen als Worte
  printed) x, " lebende und ", (ebenfalls) y " tote Gardisten.";
],


oder

Code:

describe [ i x y;
  objectloop (i in location && i ofclass Gardist) {
    x++;
    if (i has dead) y++;
  }
  print "^Im Raum sind ", (wie auch immer man Zahlen als Worte
  printed) x, " Gardisten";
  if (y) {
    print " von denen ";
    if (y == 1) print " einer tot ist";
    else print (ebenfalls) y, " tot sind";
  ".";
],


Und dann gibt's noch den Fall, dass nur ein einziger Gardist im
Raum ist, ...

Dann solltest du wahrscheinlich noch irgendeine Variable setzen,
wenn das zum ersten mal ausgespuckt worden ist, damit das nicht
für jeden Gardisten gezeigt wird, und am Ende des turns die
Variable wieder zurücksetzen, oder so.

Wie gesagt, nichts getestet, nur eine Idee.

Sophie
Nach oben
Clive
BeitragVerfasst am: Mo, 4 Aug 2003 - 18:30  Antworten mit Zitat
Wasserträger
Wasserträger


Anmeldungsdatum: 29.08.2002
Beiträge: 60

Danke, werd ich mal ausprobieren.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Clive
BeitragVerfasst am: Do, 7 Aug 2003 - 15:23  Antworten mit Zitat
Wasserträger
Wasserträger


Anmeldungsdatum: 29.08.2002
Beiträge: 60

Hm, irgendwie hab ich das Spiel nicht dazu bringen können, die Meldung bei mehreren Gardisten nur einmal auszuspucken.
Aber was anderes hat (teilweise) geklappt, und das Gute daran ist, ich kann meine Gardisten einfach vervielfältigen.

Folgend die beiden Klassen, die gebraucht werden:

Code:

Class Gardist(3)
     with   short_name "Gardist",
   plural "Gardisten",
   name 'gardist' 'gardisten',
   dekl 3,
   description "Der Gardist erwidert grimmig deine Blicke.",
   before [;
        Attack:
      Gardist.destroy(self);
      SoldatTot();
      "Er geht zu Boden und stirbt.";
        ],
     has   male animate;

Class DeadGardist(3)
     with   short_name "Gardist",
   plural "tote Gardisten",
   dekl 3,
                adj "tot",
   name 'toten' 'tote',
   description "Er sieht tot aus.",
     has   male animate;


1. Problem: Bei der Klasse DeadGardist musste ich das Adjektiv beim Plural schon in die Kurzbeschreibung setzen, weil es sonst bei mehreren Toten einfach weggelassen würde.
Kann ich das verhindern?
2. Problem: Bei derselben Klasse kann ich in der name-property nicht 'gardist' oder 'gardisten' verwenden, solange die lebenden Gardisten kein Adjektiv haben.
Wenn ich das aber vermeiden möchte, gibt es eine Möglichkeit, dass bei der Spielereingabe von 'gardist' die Klasse "DeadGardist" nur aufgerufen wird, wenn es kein Objekt mit der Klasse "Gardist" im selben Raum gibt?

Fehlen noch zwei Routinen:

Code:

[ Soldat l n;
     n = Gardist.create();
     move n to l;
];

[ SoldatTot n;
     n = DeadGardist.create();
     move n to location;
];


Und dann natürlich noch die Einträge in der Initialise-Routine, um am Anfang ein paar Gardisten zu haben:

Code:

[ Initialise;
     location = Raum;
     Soldat(Raum);
     Soldat(Raum);
     Soldat(Raum);
     "^^Test mit multiplen, sterblichen Gardisten!^^";
];



Hm, soweit meine bisherige Lösung.
Wär dankbar, wenn mir jemand sagen könnte, wie die beiden oben beschriebenen Schönheitsfehler in ihr zu bewältigen sind.


Gruß

Clive


Zuletzt bearbeitet von Clive am Fr, 8 Aug 2003 - 18:24, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Martin
BeitragVerfasst am: Fr, 8 Aug 2003 - 9:54  Antworten mit Zitat
Experte
Experte


Anmeldungsdatum: 25.08.2002
Beiträge: 677
Wohnort: München

Zitat:
Hm, irgendwie hab ich das Spiel nicht dazu bringen können, die Meldung bei mehreren Gardisten nur einmal auszuspucken.

Wie Sophie bereits geschrieben hat: Du musst eine Flagge setzen, ob der Text bereits geschrieben wurde oder nicht, etwa so:

Code:

Global Gardistenliste = 0;

Class Gardist (3) {
    with short_name "Gardist",
    ...
    describe [;
        if (Gardistenliste) return;
        Gardistenliste++;
        ! Hier Sopies Code einfügen
    ],
    each_turn [;
        Gardistenliste = 0;
    ],
    has male animate;
}


Zitat:
1. Problem: Bei der Klasse DeadGardist musste ich das Adjektiv beim Plural schon in die Kurzbeschreibung setzen, weil es sonst bei mehreren Toten einfach weggelassen würde. Kann ich das verhindern?

Hmmm. Ist hier vielleicht der List Writer nicht an die deutsche Sprache angepasst? Die Eigenschaft adj wird wohl nur zusammen mit short_name verstanden.

Zitat:
Wenn ich das aber vermeiden möchte, gibt es eine Möglichkeit, dass bei der Spielereingabe von 'gardist' die Klasse "DeadGardist" nur aufgerufen wird, wenn es kein Objekt mit der Klasse "Gardist" im selben Raum gibt?

Ja, Du kannst die Priorität von Objekten in ChooseObjects bestimmen:

Code:

[ChooseObjects obj code;
    if (code == 2) {
        if (obj ofclass Gardist) return 3;
    }
    return 1;
];


Das hat allerdings den Nachteil, dass die Wahl des Parsers in Klammern angezeigt wird und dass "leere" Befehle versuchen, etwas mit dem Gardisten anzustellen:

Code:

Ein Gardist steht hier neben zwei toten Kollegen.

> rede mit Gardist
(mit dem Gardisten)
"Tach!" Du erhältst keine Antwort.

> nimm
(den Gardisten)
Der Gardist ist dagegen.


Außerdem würde ich das verschieben der Gardisten an einen Ort direkt in der Eigenschaft create der Klassen erzeugen:

Code:

Class Gardist(3)
    with short_name "Gardist",
    ...
    create [l;
        move self to l;
    ],
    has male animate;

[ Initialise;
     location = Raum;
     Gardist.create(Raum);
     Gardist.create(Raum);
     Gardist.create(Raum);
     ...
];


Das Problem bei Deinen Ansätzen scheint mir zu sein, dass man die Klasse eines Objekts nicht während des Spiels ändern kann. Du musst also - wie Du es ja auch gemacht hast - mit parallelen Objekten für tote und lebendige Gardisten arbeiten. Oder Du arbeitest mit einer Klasse und dem Attribut dead. Dann wird die Ausgabe der Liste natürlich kompliziert.

Vielleicht solltest Du Dir mal die Lösung zur Aufgabe mit den "featureless white cubes" (Aufgabe 79) ansehen, die werden auch durch eine Klasse dargestellt und haben zwei Zustände: Entweder sind sie "featureless" oder haben einen Namen. Vielleicht kannst Du da etwas pasendes für Deine Gardisten finden.

Da Gardisten üblicherweise nicht in der Liste aller Gegenstände auftauchen, sondern in einem eigenen Absatz, muss hier wohl describe anstatt short_name und plural benutzt werden. Vielleicht kannst Du aber den List Writer für Deine Zwecke benutzen?

Und zum Schluss der Disclaimer: Der Code ist mit dem Manual überprüft, aber nicht am Rechner getestet worden.
_________________
Every silver lining has a cloud.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Clive
BeitragVerfasst am: Fr, 8 Aug 2003 - 18:23  Antworten mit Zitat
Wasserträger
Wasserträger


Anmeldungsdatum: 29.08.2002
Beiträge: 60

Juhu, endlich funktioniert alles (soweit ich das
bisher beurteilen kann) einwandfrei!
Vielen Dank an euch!
Falls das Spiel jemals fertig werden sollte, werdet
ihr beiden in der Danksagung ganz oben erwähnt. :wink:

Gruß

Clive
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Alle Zeiten sind GMT + 1 Stunde (MEZ)

Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Seite 1 von 1
if-de :: Forum Foren-Übersicht  >  Inform & Glulx

Neues Thema eröffnen   Neue Antwort erstellen


 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.



Kontakt: Administrator

Powered by phpBB and NoseBleed v1.05