Beispieldateien

Ein Ball zum Werfen

----------


// Dieser Ball besitzt eine schon komplexere Funktion für das Werfen.

// Wir leiten aus dem Standard-Objekt der Mudlib ab.
inherit "std/thing";

// Diese Headerfile enthalten alle nötigen Defines, um
// unser Objekt zu implementieren. Insbesondere sind dies
// die Propertienamen und Defines für die Bewegung von
// Objekten.
#include <properties.h> 
#include <moving.h> 

// JEDES Objekt muß diese Funktion implementiert haben.
// Sie wird vom Mudtreiber aufgerufen, wenn eine Instanz
// des Objektes erzeugt werden soll.
void create()
{
  if (!clonep()) return;
  // Ein Objekt ist dann kein 'clonep', wenn es sich nur
  // um eine Blueprint (sozusagen eine Objektvorlage) handelt.
  // Um Speicher zu sparen wird das 'create' für Blueprints
  // nicht ausgeführt.

  ::create();
  // Hiermit rufen wir das aus dem inheriteten Objekt geerbte
  // 'create' auf. Dies ist ABSOLUT notwendig, da dort wichtige
  // Initialisierungen durchgeführt werden.

  AddId(({"ball", "strandball", "\n_bsp_strandball"}),
    ({"baelle", "strandbaelle"}));
  // Mit AddId wird angegeben, unter welchen Bezeichnungen dieses
  // Objekt vom Spieler angesprochen werden kann. Hier sollte man
  // immer genügend viele Angaben machen, damit die Spieler nicht
  // lange nach der richtigen Bezeichnung suchen müssen.
  // Die Id "\n_bsp_strandball" ist für eine eindeutige Kenn-
  // zeichnung des Objektes gedacht. das '\n' wird als 'newline'
  // behandelt und kann von Spielern nicht eingegeben werden.

  SetProp(P_NAME, "Standball");
  SetProp(P_PLURAL, "Strandbaelle");
  SetProp(P_GENDER, MALE);
  SetProp(P_ARTICLE, ART_AUTO);
  // Diese Angaben ermöglichen es der Mudlib, das Objekt stets
  // richtig zu deklinieren. P_NAME stellt den Namen des Objektes
  // im Singular, P_PLURAL den für den Plural dar.
  // Das grammatikalische Geschlecht des Objektes ist männlich,
  // und es wird je nach Notwendigkeit ein bestimmter oder un-
  // bestimmter Artikel benutzt.

  SetProp(P_NAME_ADJ, ({"gelb", "getuepfelt" }));
  AddAdjective(({"gelber", "gelbe", "gelbem", "gelben", "getuepfelter",
    "getuepfelte", "getuepfeltem", "getuepfelten"}));
  // Mit diesen Befehlen werden die Ajektive des Balles definiert.
  // Er soll hier gelb getüpfelt sein. Mit dem ersten Befehl werden
  // die Ajektive mit dem Namen dekliniert und ausgegeben. Durch den
  // zweiten Befehl läßt sich der Ball von Spielern auch als
  // "gelber ball" oder "getüpfelten ball" oder "gelbe getüpfelte
  // ball" ansprechen (erweiterte Id)

  SetProp(P_LONG, "Was fuer ein huebscher kleiner Strandball."
    " Wem koenntest Du ihm den mal zuwerfen?" );
  // Die Property P_LONG beinhaltet die Langbeschreibung des Objektes.
  // Sie wird z.B. beim Untersuchen des Balles an den Spieler ausgegeben.

  AddDetail(({"farbe", "tupfen"}),
    "Der Ball ist weiss mit gelben Tupfen.");
  // Mit AddDetail können wir dem Ball ein paar untersuchbare Details
  // hinzufügen. So kann ein Spieler jetzt z.B. die Tupfen an dem
  // Ball untersuchen. Mit Details sollte man nie sparsam sein, denn
  // sie sorgen für die Atmospähre :)

  SetProp(P_VALUE, 50);
  SetProp(P_WEIGHT, 250);
  SetProp(P_BULKINESS, 40);
  // Diese Werte spezifizieren die physikalischen Eigenschafen wie
  // Gewicht (250 Gramm) und 'Größe' (40) des Objektes. P_VALUE
  // gibt den Wert des Objektes in Bernsteinen (hier 50) an.
  // Bei diesen Werten sollte die Verhältnismäßigkeit nicht
  // aus den Augen gelassen werden.

  AddCmd("wirf|werf|werfe", "wurf");
  // Hiermit definiert man die spezielle Aktion des Werfens, welche
  // mit diesem Ball möglich ist. Dafür wird dann die untenstehende
  // Funktion "wurf" ausgeführt, falls der Spieler das Kommando
  // werfe, werf oder wirf eingibt. Man sollte darauf achten, daß
  // natürliche Sätze als Eingabe akzeptiert werden.
}

/*******************************************/
/* Die grundlegenden Funktionen enden hier */
/*******************************************/

// Eine Beispielaktion für den Ball.
//
// Diese Funktion wird aufgerufen, wenn der Spieler in der 'Nähe'
// (also wenn der Ball sich im Inventory des Spielers befindet, oder
// wenn sich Ball und Spieler im gleichen Container (z.B. einem Raum)
// aufhalten) des Balles eines der mit AddCmd angegebenen Kommandos
// benutzt.
//
// Derartige Funktionen haben stets die Form:
//  int funktionsname(string argument)
//
// Falls die Funktion mit dem Kommando nichts anfangen kann, so ist
// 0 zurückzugeben. Wenn das Kommando erfolgreich bearbeitet wurde,
// ist 1 zurückzugeben. Falls die Funktion mit 0 beendet wurde, und
// kein weiteres Objekt in der Nähe des Spielers auf das benutzte
// Kommando reagiert, so gibt der Treiber den mit notify_fail an-
// gegebenen Fehlertext an den Spieler aus und beendet die Abarbeitung
// des Kommandos. (Es wird immer das zuletzt angegebene notify_fail
// verwendet!)
//
// Im übergebenen Argument steht der NACH dem Verb eingegebene Text
// (Bei 'wirf ball zu elric' also 'ball zu elric') oder 0, falls kein
// Text angegeben wurde.
int wurf(string argument)
{
  string dummy1, dummy2;
  string ziel;
  object zielObj;

  notify_fail("WAS willst Du WEM zuwerfen?\n");
  // Diese Meldung wird ausgegeben, falls diese Funktion eine 0
  // als Ergebnis hat und danach keine weitere Funktion zu diesem
  // Kommando aufgerufen werden konnte.

  if (!stringp(argument) || !strlen(argument)) return 0;
  // Wenn kein Argument übergeben wurde, oder das Argument nicht
  // vom Typ String ist, hat der Spieler nur das Kommando angegeben,
  // nicht aber wem er was zuwerfen will. Daher geben wir hier 0
  // zurück denn ohne diese Information können wir nichts sinnvolles
  // tun.

  argument = lower_case(argument);
  // Hier wandeln wir den String in Kleinbuchstaben um, falls
  // der Spieler etwas Eigennamen groß geschrieben hat.

  if ((sscanf(argument, "%s %s zu", dummy1, dummy2 ) != 2) &&
    (sscanf(argument, "%s zu %s", dummy1, dummy2) != 2)) return 0;
  // Wenn der string argument in keines der beiden Muster paßt, dann
  // kann die Funktion mit dem argument nichts anfangen. Möglich wird
  // durch die zweite Form auch ein "wirf elric zu ball". Sollte
  // jemand so etwas tippen, macht das aber auch nichts.

  if (id(dummy1)) ziel = dummy2;
  else  if (id(dummy2)) ziel = dummy1;
    else return 0;
  // Welches der Argumente spricht den Ball an? Das andere muß dann
  // das Ziel des Balls sein. Falls keines der Argumente den Ball
  // bezeichnet, können wir mit dem Kommando nichts anfangen und
  // geben daher 0 zurück.

  zielObj = present(ziel, environment(this_player()));
  // Wir suchen ein Objekt in der Umgebung des Spielers,
  // welches sich durch 'ziel' angesprochen fühlt.

  if (!objectp(zielObj))
  {
    tell_object(this_player(), break_string("Hier ist kein '" +
      capitalize(ziel) + "'."));

    return 1;

    // Wir haben kein passendes Objekt gefunden und geben daher
    // eine Fehlermeldung aus. Außerdem wird 1 zurückgegeben,
    // da der Ball das Kommando bearbeiten konnte. Er hat zwar
    // kein Ziel gefunden, aber man kann ja nicht alles haben...
  }

  if (!living(zielObj))
  {
    tell_object(this_player(), break_string("Und wie soll " +
      zielObj->name(WER, NAME_DEF) + " den Ball fangen?"));

    return 1;

    // Nur lebende Wesen sollen Bälle fangen können. Das Define
    // ART_DEF im Aufruf von name(...) erzwingt die Verwendung eines
    // bestimmten Artikels (der, die, das).
  }

  tell_object(this_player(), break_string(sprintf("Du wirfst %s den Ball zu.",
    zielObj->name(WEM, NAME_DEF))));
  tell_room(environment(this_player()), break_string(sprintf("%s wirft %s einen"
    " Ball zu.", this_player()->name(WER, NAME_AUTO|NAME_CAP),
    zielObj->name(WEM, NAME_AUTO))), ({zielObj, this_player()}));
  tell_object(zielObj, break_string(sprintf("Hoppla, %s wirft Dir einen Ball"
    " zu.", this_player()->name(WER, NAME_AUTO|NAME_CAP))));
  // Hier geben wir die Meldungen aus. Die erste geht an den Spieler, die
  // zweite an alle im Raum befindlichen außer dem Werfenden und dem Ziel
  // und die letzte an das Zielobjekt.

  if (move(zielObj, M_PUT) >= MOVE_OK) return 1;
  // 'move' bewegt das Objekt und das 'zielObj' und benutzt dabei die
  // Methode M_PUT. 'Geben' ist zwar nicht ganz der richtige Ausdruck,
  // kommt aber am nächsten an den Sachverhalt heran.

  move(environment(this_player()), M_DROP);
  // Falls die Bewegung zum Zielobjekt aus irgendeinem Grund nicht
  // klappt, so soll der Ball zu Boden fallen.

  tell_room(environment(this_player()), break_string(sprintf("Aber %s kann ihn nicht"
    " fangen und der Ball plumpst zu Boden.", zielObj->QueryPronoun(WER))),
    ({zielObj}));
  tell_object(zielObj, break_string("Aber Du kannst ihn nicht fangen. Der Ball"
    " plumpst zu Boden."));
  // Hier geben wir nochmal Meldungen aus. Die erste an alle im Raum außer
  // dem Fangenden und die andere an den Fangenden.

  return 1;
  // Fertig, jetzt können wir die Funktion mit 1 (Erfolg) beenden.
}