Debuggen mit dtell()


Hallo,

die Funktion dtell() ist für das Debuggen von Code gedacht. Sie ist in der secure/simul_efun.c definiert.

Syntax: dtell(mixed wem,mixed was,string idt);

wem
Magiername oder Array mit mehreren Magiernamen
was
Array, String, Mapping etc.
idt
Optionaler String, der jeder Zeile vorangestellt ist

Mit dtell() kann man sich eigene Texte oder die Inhalte von Variablen anzeigen lassen. dtell() ist AnderLand spezifisch, in anderen MUDs mag es andere Lösungen geben.

Vorteile von dtell(): Mit dtell() kann es nicht passieren, dass der Code buggt, wenn der debuggende Magier nicht anwesend ist. Vor dtell() wurden oft solche Konstrukte benutzt:

  • tell_object(find_player(“magiername”),”Meine Debugmeldug.\n”);
    Buggt, wenn der Magier ‘magiername’ nicht im AnderLand ist. Die Abfrage nach der Anwesenheit des Magiers wird gerne mal unterschlagen (z.B. aus Faulheit).

  • DD(x) tell_object(find_player(“magiername”)||this_object(), x)
    Hat den Nachteil, dass man das irgendwo definieren muss. Hat man kein zentrales Header-File, muss man das immer wieder irgendwo eintragen.

Es gibt bestimmt noch etliche andere Lösungen, doch alle sind irgendwie umständlich oder fehleranfällig.

Mit dtell() kann man Debugging z.B. so realisieren:

public void test()
{
  int i,j;
  mapping map;
  string *arr;

   i = 1;
   j = 2;

   map = (["test": 3]);

   arr = ({1,2,3});

   // Eine Meldung an It
   dtell("it","Mal schauen, ob das Programm bis hierher kommt.");
     // Das sieht dann wie folgt aus:
     //  [DTELL] /players/it/test/test
     //  [DTELL] Mal schauen, ob das Programm bis hierher kommt.

   
   // Eine Meldung an It und Harrypotter
   dtell( ({"it","harrypotter"}),"Meldung an mehrere Magier.");

   // Man kann sich natürlich auch eine Variable anzeigen lassen:
   dtell( ({"it"}),i);
     // Das sieht dann wie folgt aus:
     //  [DTELL] /players/it/test/test
     //  [DTELL] 1

   // Oder auch mehr als eine Vatiable:
   dtell( ({"it"}), ({ i,j }) );
     // Das sieht dann wie folgt aus:
     //  [DTELL] /players/it/test/test
     //  [DTELL] ({ /* #1, size: 2 */
     //  [DTELL]   1,
     //  [DTELL]   2
     //  [DTELL] })

   // natürlich kann man auch Arrays wie Mappings anzeigen:
   dtell( ({"it"}), map);
    // Das sieht dann so aus:
    //  [DTELL] /players/it/test/test
    //  [DTELL] ([ /* #1 */
    //  [DTELL]   "test": 3
    //  [DTELL] ])

   // oder alles auf einmal, indem man diese Variablen ebenfalls in ein
   // Array packt und sich dieses anzeigen lässt:
   dtell( "it", ({i, j, map, arr}) );
     // Das sieht dann so aus:
     //  [DTELL] /players/it/test/test
     //  [DTELL] ({ /* #1, size: 4 */
     //  [DTELL]   1,
     //  [DTELL]   2,
     //  [DTELL]   ([ /* #2 */
     //  [DTELL]     "test": 3
     //  [DTELL]   ]),
     //  [DTELL]   ({ /* #3, size: 3 */
     //  [DTELL]     1,
     //  [DTELL]     2,
     //  [DTELL]     3
     //  [DTELL]   })
     //  [DTELL] })

}

Fazit: Nicht verzweifeln und öfters mal dtell() benutzen 🙂

Gruß,

– It –

Code: Valider NPC für das AnderLand (Properties)

Im AnderLand müssen NPCs bestimmte Properties enthalten. Leider werden immer wieder welche vergessen. Hier folgt ein NPC, den man als Vorlage benutzen kann, der die Properties enthält, die auf jeden Fall IMMER gesetzt werden müssen:

// npc.c - Ein minimaler NPC

#pragma strong_types

#include <properties.h>
#include <language.h>
#include <combat.h>
#include <moving.h>

inherit "/std/npc";

void create()
{
  if (!clonep())
  {
    set_next_reset(-1);
    return;
  }
  ::create();
  
// Folgende Dinge MUESSEN IMMER gesetzt sein:

  // Setzt schonmal alle Grundwerte für einen NPC mit Level 5
  create_default_npc(5); 

  // Die ID des Hasen, mit der man ihn bei 'untersuche', 'toete' etc
  // ansprechen kann.  
  AddId(({"hase","meister lampe","tier"}));

  // Der Name des NPCs
  SetProp(P_NAME,"Hase");

  // Das Geschlecht: NEUTER, MALE oder FEMALE
  SetProp(P_GENDER,MALE); 

  // Die Kurzbeschreibung, sieht man, wenn man im Raum 'schau' eingibt.
  SetProp(P_SHORT, "Ein Hase"); 

  // Die Langbeschreibung, sieht man, wenn man 'untersuche Monster'
  SetProp(P_LONG,"Ein grauer Hase."); 

  // Die Groesse in Zentimeter
  SetProp(P_SIZE,40);

  // Das Gewicht in Gramm
  SetProp(P_WEIGHT,3000);
  
  // Die Klassen, bitte richtig und möglichst komplett setzen, 
  // da sie im Spiel an vielen Stellen benutzt werden! Alle 
  // Klassen findet man in /sys/class.h
  // Bedeutungen: CL_FUR -> Hase hat Fell, 
  //              CL_ANIMAL -> Hase ist ein Tier,
  //              CL_WALKING -> Hase bewegt sie gehend fort,  
  //              CL_MAMMAL -> Hase ist ein Saeugetier, 
  //              CL_MAMMAL_LAND -> Hase ist ein Landsaeuger, 
  //              CL_RABBIT -> Hase ist ein Hase 🙂

  AddClass(({CL_FUR,CL_ANIMAL,CL_MAMMAL,CL_WALKING,CL_MAMMAL_LAND, 
             CL_RABBIT}));

  // Die Rasse des Hasen
  SetProp(P_RACE,CL_RABBIT);

// Folgende Dinge sollten gesetzt werden.
 
  // Die Details des Hasen 
  AddDetail({"ohr","ohren"}),"Die Ohren sind enorm lang.");

  AddDetail(({"fell","hasenfell"}),"Das Fell ist grau.");

  // Womit greift der Hase an und wieviel Schaden macht er:
  // DT_WHIP -> Peitschender Schaden.
  // Alle Schaeden, die es gibt, kann man in /sys/combat.h
  // nachlesen.
  SetProp(P_HANDS,({ " mit seinen Ohren",30, DT_WHIP }));

  // Die Gesinnung des Hasen. Bei NPCs vom -1500 (satanisch)
  // bis +1500 (heilig)
  SetProp(P_ALIGN,300);

// Folgendes Sachen waeren schoen:
  // Die In-/Out- Medlungen

    // Meldungen bei 'normaler' Bewegung
  SetProp(P_MSGIN,    "hoppelt herein");
  SetProp(P_MSGOUT,   "hoppelt");

    // Bei Teleport, wo es keine Richtungen bei der Bewegung gibt
  SetProp(P_MMSGOUT,  "hoppelt davon");
  SetProp(P_MMSGIN,   "hoppelt herein");

  // Die Kampfpunkte, die ein Npc gibt. Muss man normalerweise
  // nicht setzen, da dies automatisch berechnet wird. Moechte
  // man aber eine Bonus darauf geben, geht das wie folgt (und
  // zwar IMMER GANZ AM ENDE VON CREATE! Im Beispiel: 1000
  // Bonus fuer den Kill.
  SetProp(P_XP,suggest_xp(1000));
}

Natürlich kann man noch viel viel mehr in einem NPC setzen. Wenn Du nicht weißt, wie etwas geht oder was noch möglich ist, einfach mal einen Magier Deiner Wahl im AnderLand fragen!

Gruß,

– It –

Die Programmier – Gebote


Im AnderLand gibt es einige Regeln, an die man sich als Magier halten sollte.

Leider gibt es immer Programmierer, die nicht einsehen, warum sie sich daran halten sollten. Meist hört man dann Argumente wie: ‘Warum keine Tabs, bei mir sieht das doch gut aus’, ‘Warum nur 78 Zeichen pro Zeile, mein Monitor schafft das Vierfache’ oder ‘Warum soll ich die vordefinierten Defines benutzen’ etc.

Die einfache Erklärung für fast alle Regeln ist: Wir Programmieren im AnderLand mit den unterschiedlichsten Tools und mit verschiedenen Betriebssystemen. Manch einer benutzt einen einfachen Editor in einer Textkonsole, der andere eine IDE mit allem drum und dran. Daher müssen wir uns auf den kleinsten Nenner einigen und der ist in diesen Regeln zusammen gefasst:

1. Du sollst keine Tabs verwenden.

2. Du sollst nicht mehr als 78 Zeichen in eine Zeile packen.

3. Du sollst keine Klammern statistisch über das Programm verteilen. Man muss erkennen, welche Klammer zu welchem Befehl gehört.

4. Du sollst sauber einrücken. Hinter einer Klammer haben in der nächsten Zeile mind. 2 Leerzeichen zu folgen. (aber beachte Punkt 1!)

5. Du sollst, wo es geht, keine globalen Variablen benutzen.

6. Du sollst Deinen Funktionen und Variablen einen Typen zuweisen.

7. Du sollst die Defines aus /sys/ benutzen, auch wenn Du z.B. selbst weißt, dass NEUTER = 0 ist…

8. Du sollst keine call_outs starten, wenn du nicht überprueft hast, ob bereits ein call_out läuft.

9. Du sollst überpruefen, ob ein Spieler das Objekt, dass du in ihn bewegen willst, überhaupt noch tragen kann.

10. Du sollst keine Objekte in Geister bewegen (und beachte Punkt 9!).

11. Du sollst überprüfen, ob ein Objekt überhaupt existiert, bevor Du mit dem Objekt etwas anstellen willst. Beachte, dass dies auch und besonders für call_out-Funktionen gilt. Wenn Zeit verstreicht, kann ein Objekt zwischendurch zerstört worden sein.

12. Du sollst gut lesbar proggen, auch wenn du weißt, wie man proggt, damit niemand mehr den Code versteht (siehe Punkt 1 bis 7).

13. Du sollst in den Kopf einer Datei schreiben, wer sie wann geändert hat. (Beachte hierbei aber Punkt 1 und Punkt 2!)

14. Du sollst für ascii-Grafiken Alternativen für P_SIMPLE_MODE anbieten. AddDetail und AddReadDetal haben schon entsprechende Parameter, um dir die Arbeit zu erleichtern!

15. Du sollst Alternativen für P_SIMPLE_MODE anbieten, wenn du einem NPC oder Raum scheinbar etwas sagen lässt. Z.B. write(break_string(“Hallo”,0,”Der Mann sagt: “); lautet für P_SIMPLE_MODE:
write(break_string(“Hallo”,0,”Der Mann sagt:”,BS_INDENT_ONCE);
Teste dies! Das sind verschiedene Ausgaben, wenn der Text über mehrere Zeilen geht!

16. Du sollst keinen Müll hinterlassen. Lösche nach Beendigung deines Projektes in /d/ alle *.bat, *.bak, *.old, *.older, *.orig, *~ (und wie sie alle heißen) Files, entferne ebenso Verzeichnisse, die nicht mehr gebraucht werden oder auch Objekte, die Du gar nicht anschließen willst!

17. Du sollst für Befehle keine Defines benutzen. Kein BS, kein TP, kein TPN und TPn und TPU und wie sie alle heißen. Auch andere müssen evtl. deinen Code verstehen und debuggen können!

18. Du sollst, wenn du mit Geld arbeitest, die ZENTRALBANK benutzen. Wenn du nicht weißt, wie das geht, dann melde dich bei einem Magier, der dir helfen kann!

Magier: Klassen im Anderland

Bild: Binär

Hallo zusammen!

Das Anderland hat, wie ihr natürlich schon lange wisst, ein recht großes Klassensystem. Dies wurde jetzt nochmal von It und mir erweitert. Die Manpages wurden auch entsprechend überarbeitet:

-> “man AddClass”, “man RemoveClass”, “man is_class_member”.

Ganz neu hierbei sind Klassen nach Bewegung: CL_WALKING, CL_FLYING etc. Dies könnte für kommende Dinge evtl. nicht ganz unwichtig sein. 😉

Bitte denkt weiterhin daran, in jedem neuen NPC die passenden Klassen zu setzen. Dies ist für die Spieler und das Spiel von großer Bedeutung.

Falls Euch auffällt, dass eine wichtige Klasse fehlt, sprecht uns bitte an.

Weiterhin viel Spaß beim Programmieren wünscht Euch

Torin

Magier: Freie Hände

Bild: Binär
Hallo zusammen!

Wieder eine neue Sache, diesmal mit einer kleinen Umstellung verbunden: die (freien) Hände werden neu/anders verwaltet.

Ab sofort solltet ihr, wenn ihr auf freie Hände testet, P_FREE_HANDS nutzen. P_USED_HANDS gibt es nämlich ab nächstem Reboot nicht mehr. 🙂 (Eure Objekte braucht ihr aber nicht zu ändern, das machen It und ich).

Weitere neue Funktionen in diesem Zusammenhang: UseHands() und FreeHands().

Neue Manpages: UseHands, FreeHands, P_HANDS_USED_BY, P_FREE_HANDS

Weiterhin viel Spaß beim Programmieren wünscht euch

Torin