Codefreeze

Bild: Globus
Moin moin,

wir stellen das AnderLand gerade auf den Driver 3.5 um. Da dies parallel im einem Testmud passiert, herrscht ab jetzt hier ein Codefreeze.

Alle Änderungen an Files aus dem System aber auch in /d/ /p/weapon/ und /p/armour/ werden verloren gehen, da wir nach den Anpassungen alle Files vom 6.7.2018 zurück spielen werden!

Gruß,

– It –

Objekt Tests bei call_out()


Hallo,

Bei der Durchsicht von fremden Code ist mir aufgefallen, dass oftmals vergessen wird abzufragen, ob ein Objekt überhaupt noch existiert oder es sich noch im Raum befindet, bevor damit irgend etwas angestellt wird. Besonders wenn Zeit vergangen ist (z.B. durch call_out()), kann dies zu Bugs führen. Das scheint ein beliebter Anfängerfehler zu sein.

Hier ein Beispiel, wie man es nicht machen sollte:


#pragma strong_types

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

inherit "/std/room";

protected void create()
{
  ::create();

  SetProp(P_INT_SHORT, "Ein Raum");
  SetProp(P_INT_LONG,  "Ein Raum.");
  SerProp(P_INT_LONG_EXT,"Ein Baum.\n");
  SetProp(P_LIGHT,1);

  AddCmd(({"lach","lache"}),"lachen_act")
}

static void message(object pl)
{
  // Medlung an Spieler
  tell_object(pl,"Der Baum schaut Dich verwundert an.\n");
}

static int lachen_act(string str)
{
  if(find_call_out("message") == -1)     // call_out() läuft noch nicht
    call_out("message",2,this_player()); // Meldung per call_out() starten

  return 0;
}

In der Funktion message(), die per call_out() aufgerufen wird, wird hier dem Spieler eine Nachricht per tell_object() gesendet. Das Problem hierbei ist aber, dass bis zum Aufruf von message() Zeit vergeht. In dieser Zeit kann der Spieler das Mud (der Objekt-Pointer ist dann weg) oder den Raum verlassen haben. Im ersten Fall gibt es einen Fehler, im zweiten Fall bekommt der Spieler die Nachricht, obwohl er gar nicht mehr im diesem Raum steht.

Hier mal eine bessere Funktion fuer message()

static void message(object pl)
{
  if(objectp(pl)) // existiert das Spielerobjekt überhaupt noch...
    if(present(pl,this_object())) // steht der Spieler noch in diesem Raum
      // Medlung an Spieler
      tell_object(pl,"Der Baum schaut Dich verwundert an.\n");
}

Das gilt natürlich nicht nur für Spieler und Räume, sondern immer dann, wenn mit Objekten über call_out() etwas angestellt werden soll.

Gruß,

– It –

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 –

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