diff --git a/std/items/kraeuter/trank.c b/std/items/kraeuter/trank.c
new file mode 100644
index 0000000..f3c0efe
--- /dev/null
+++ b/std/items/kraeuter/trank.c
@@ -0,0 +1,1147 @@
+//TODO:
+
+#pragma strong_types,rtt_checks
+
+inherit "/std/thing";
+
+#include <properties.h>
+#include <defines.h>
+#include <items/kraeuter/kraeuter.h>
+#include <items/kraeuter/trankattribute.h>
+#include <hook.h>
+#include <class.h>
+#include <new_skills.h>
+#include <wizlevels.h>
+
+#ifndef BS
+#  define BS(x)             break_string(x, 78)
+#endif
+
+#define allowed(x) (object_name(x)==PLANTMASTER)
+#define DRINK_POTION "lib_kraeutertrank_trinken"
+// for debug
+#define private public
+
+// Ablaufzeit des Tranks, ab dann keine Wirkung mehr
+private nosave int expiry;
+// Ablaufzeit der wirkungen des Trankes (0, wenn Trank nicht getrunken)
+private nosave int duration;
+// Trankattribute, vom Krautmaster schon skaliert, gekappt, beschraenkt auf
+// die jeweils max. positiven Effekte
+private nosave mapping data;
+// Klassen, die bei Schutz oder verstaerktem Schaden betroffen sind. Werte
+// ist der Schutz- oder Attackebonus/-malus.
+private nosave mapping att_classes;
+private nosave mapping prot_classes;
+// max. Summe von Giftstufen (P_POISON und P_LEVEL/10 bei CL_POISON).
+private nosave int prot_poison;
+// max. geheilte Summe von Krankheitslevel (P_LEVEL/5 in CL_DISEASE).
+private nosave int prot_disease;
+// nach Wirkung absteigend sortierte Liste der Effekte, wird beim ersten
+// Aufruf von DetermineStrongesEffect() befuellt.
+private nosave string* sorted_effects;
+
+mixed _query_data() {return data;}
+int _set_data(mixed d) {data=d; expiry = __INT_MAX__; return data!=0;}
+private string effect2colour();
+
+protected void create()
+{
+  if (object_name(this_object()) == __FILE__[0..<3])
+  {
+    set_next_reset(-1);
+    return;
+  }
+  ::create();
+  SetProp(P_GENDER, FEMALE);
+  SetProp(P_NAME, "Glasflasche");
+  SetProp(P_NAME_ADJ, ({"klein"}));
+  SetProp(P_VALUE, 10);
+  SetProp(P_WEIGHT, 100);
+  SetProp(P_KILL_NAME, "Ein Kraeutertrank");
+  SetProp(P_KILL_MSG, "%s hat sich wohl beim Anruehren vertan.");
+  AddId(({"glasflasche", "flasche"}));
+  AddAdjective(({"klein", "kleine"}));
+  AddCmd("trink|trinke&@ID", "cmd_trinken",
+    "Was willst Du trinken?");
+}
+
+protected void create_super()
+{
+  set_next_reset(-1);
+}
+
+static string _query_short()
+{
+  if (!clonep(ME))
+    return "Eine kleine Glasflasche";
+  return Name(WEN, 0)+(data==0 ? "" : " (gefuellt)");
+}
+
+static string _query_long()
+{
+  if (data==0)
+    return break_string(
+      "Eine kleine leere Glasflasche, die mit einem Korken verschlossen "
+      "ist.\n"
+      "Flaschen wie diese werden ueblicherweise verwendet, um darin "
+      "magische Traenke abzufuellen.", 78, 0, BS_LEAVE_MY_LFS);
+
+  return break_string(
+    "Eine kleine Glasflasche, die mit einer "+effect2colour()+"en "
+    "Fluessigkeit gefuellt ist.\n"
+    "Sie ist mit einem Korken verschlossen, um den Inhalt der "
+    "Flasche zu schuetzen.",78, 0, BS_LEAVE_MY_LFS);
+}
+
+private string num2desc(int bumms)
+{
+  switch(abs(bumms))
+  {
+    case 0..499:
+      return "ein wenig";
+    case 500..999:
+      return "so einiges";
+    case 1000..1499:
+      return "erheblich";
+    case 1500..2000:
+      return "unglaublich";
+  }
+  return "ungenehmigt viel"; // kommt hoffentlich nicht vor.
+}
+
+varargs private string DetermineStrongestEffect(int pos)
+{
+  // globale Werteliste befuellen, wenn da noch nichts drinsteht.
+  if ( !pointerp(sorted_effects) ) {
+    sorted_effects = sort_array(m_indices(data) & T_KRAUT_EFFECTS,
+      function int (string a, string b) {
+        return (abs(data[a])<=abs(data[b]));
+      });
+  }
+
+  // Zur Indizierung des Arrays muss <pos> bei Null starten, es wird
+  // aber mit der Bedeutung einer Ordinalzahl (erste, zweite, dritte, ...)
+  // uebergeben. Daher um 1 reduzieren.
+  --pos;
+
+  string ret;
+
+  // Im Array muss mindestens ein Eintrag stehen, sonst gibt's gar keinen
+  // Effekt.
+  if ( sizeof(sorted_effects) )
+  {
+    // Wenn der angefragte Index ausserhalb der Arraygrenzen liegt, wird
+    // angenommen, dass der erste bzw. letzte Eintrag gesucht waren.
+    if ( pos < 0 )
+      ret = sorted_effects[0];
+    else if ( pos >= sizeof(sorted_effects) )
+      ret = sorted_effects[<1];
+    else
+      ret = sorted_effects[pos];
+  }
+  return ret;
+}
+
+// Liefert zu dem maximal wirksamen Effekt die Farbe des Trankes zurueck.
+private string effect2colour()
+{
+  // Ist die Haltbarkeit schon abgelaufen, wird der Trank farblos.
+  if ( time() > expiry )
+    return "farblos";
+
+  // Namen des staerksten Effekts holen.
+  string effect = DetermineStrongestEffect(1);
+  mapping colours = ([
+    T_CARRY:              "trueb braun",
+    T_DAMAGE_ANIMALS:     "blutrot",
+    T_DAMAGE_MAGIC:       "oktarinfarben",
+    T_DAMAGE_UNDEAD:      "anthrazitfarben",
+    T_FLEE_TPORT:         "schwefelgelb",
+    T_FROG:               "schlammgruen",
+    T_HEAL_DISEASE:       "perlmuttfarben",
+    T_HEAL_POISON:        "gruen",
+    T_HEAL_SP:            "blau",
+    T_HEAL_LP:            "scharlachrot",
+    T_PROTECTION_ANIMALS: "metallisch grau",
+    T_PROTECTION_MAGIC:   "violett",
+    T_PROTECTION_UNDEAD:  "strahlend weiss",
+    T_SA_SPEED:           "orangefarben",
+    T_SA_SPELL_PENETRATION: "stahlblau",
+    T_SA_DURATION:        "pinkfarben",
+  ]);
+  string ret = colours[effect];
+  return stringp(ret) ? ret : "farblos";
+}
+
+// Wird gerufen, wenn die Wirkung des Trankes ablaufen soll.
+private void terminate_effects()
+{
+  tell_object(environment(),
+      "Die letzten Wirkungen des Kraeutertrankes klingen ab.\n");
+  remove(1);
+}
+
+// Von den Hooks H_HOOK_ATTACK_MOD und H_HOOK_DEFEND gerufen, erhoeht oder
+// verringert den Schaden gegen Lebenwesen bestimmter Klassen (Keys in
+// <classes>). Der Malus/Bonus steht als Wert zum jeweiligen Key in dem
+// Mapping.
+mixed hcallback(object hookSource, int hookid, mixed hookData)
+{
+    if (hookSource != environment())
+        return ({H_NO_MOD,hookData});
+    switch(hookid)
+    {
+      case H_HOOK_ATTACK_MOD:
+        foreach(string class, int modval : att_classes)
+        {
+          if (hookData[SI_ENEMY]->is_class_member(class))
+          {
+            // Yeah. Treffer. Schaden erhoehen oder verringern... ;)
+            hookData[SI_SKILLDAMAGE] += modval;
+            // Ende. keine weiteren Klassen pruefen.
+            return ({H_ALTERED, hookData});
+          }
+        }
+        break;
+      case H_HOOK_DEFEND:
+        // hookData: ({dam,dam_type,spell,enemy})
+        foreach(string class, int modval : prot_classes)
+        {
+          if (hookData[3]->is_class_member(class))
+          {
+            // Yeah. Treffer. Schaden erhoehen oder verringern... ;)
+            hookData[0] += modval;
+            // Ende. keine weiteren Klassen pruefen.
+            return ({H_ALTERED, hookData});
+          }
+        }
+        break;
+      case H_HOOK_INSERT:
+        // Wenn die Giftschutzkapazitaet noch ausreicht, wird das reinkommende
+        // Objekt zerstoert (und die Kapazitaet reduziert).
+        // hookData: neues object
+        if (prot_poison > 0
+            && hookData->is_class_member(CL_POISON))
+        {
+          // kostet ein Zehntel des Levels, aber min. 1.
+          int p=hookData->QueryProp(P_LEVEL) / 10 + 1;
+          if (p < prot_poison)
+          {
+            hookData->remove(1);
+            prot_poison-=p;
+            return ({H_CANCELLED, hookData});
+          }
+        }
+        // Wenn die Krankheitsschutzkapazitaet noch ausreicht, wird das reinkommende
+        // Objekt zerstoert (und die Kapazitaet reduziert).
+        // hookData: neues object
+        if (prot_disease > 0
+            && hookData->is_class_member(CL_DISEASE))
+        {
+          // kostet ein Fuenftel des Levels, aber min. 1.
+          int lvl = hookData->QueryProp(P_LEVEL) / 5 + 1;
+          if (lvl < prot_disease)
+          {
+            hookData->remove(1);
+            prot_disease-=lvl;
+            return ({H_CANCELLED, hookData});
+          }
+        }
+        break;
+      case H_HOOK_POISON:
+        // hookData: poisonval
+        // Alle Giftlevel werden reduziert auf 0 und von prot_poison
+        // abgezogen. Wenn das 0 ist, endet der Giftschutz.
+        if (prot_poison>0)
+        {
+          if (hookData < prot_poison)
+          {
+            prot_poison-=hookData;
+            hookData = 0;
+          }
+          else
+          {
+            hookData -= prot_poison;
+            prot_poison=0;
+          }
+          return ({H_ALTERED, hookData});
+        }
+        break;
+    }
+    return ({H_NO_MOD, hookData});
+}
+
+private int reg_hook(int hook, int hooktype)
+{
+  // Wenn schon registriert, zaehlt das auch als Erfolg.
+  if (environment()->HIsHookConsumer(hook, #'hcallback))
+    return 1;
+  int res = environment()->HRegisterToHook(hook, #'hcallback,
+                 H_HOOK_OTHERPRIO(0), hooktype, duration);
+  if (res <= 0)
+  {
+    // wenn andere Fehler als -7 (zuviele Hooks registriert) vorkommen:
+    // Fehlermeldung ausgeben
+    if (res != -7)
+      tell_object(environment(),break_string(sprintf(
+          "Technischer Hinweis, den Du an einen Magier weitergeben "
+          "solltest: Beim Registrieren des Hooks %d gab es Fehler: %d\n",
+          hook, res),78));
+    return 0;
+  }
+  return 1;
+}
+
+// effekt: Wirkungswert des Tranks (muss negativ sein)
+// type: 1 fuer Gift, 0 fuer Krankheit
+private void ticktack(int effekt, int type)
+{
+  // Schaden tickt alle 5 Sekunden
+  int delay = 5;
+  // Der halbe Betrag des negativen Effekts wird als Schaden am
+  // Spieler verursacht.
+  // Berechnung: (Schaden pro Sekunde) * (Delay in Sekunden)
+  // in float rechnen ist hier sinnvoll, inkl. aufrunden (durch die +0.5)
+//  int dam = to_int(((-0.5*effekt)/duration)*delay + 0.5);
+  int dam = to_int(0.5*abs(effekt)/data[T_EFFECT_DURATION]*delay + 0.5);
+
+  if (type)
+    tell_object(environment(),
+      break_string("Gift pulsiert brennend durch Deine Adern.",78));
+  else
+    tell_object(environment(),
+      break_string("Du fuehlst Dich schwach und elend, eine Erkrankung "
+      "zehrt an Deinen Kraeften.",78));
+
+  environment()->do_damage(dam, this_object());
+  call_out(#'ticktack, delay, effekt, type);
+}
+
+private int act_attr_heal_poison(int effekt)
+{
+  int erfolgreich;
+  tell_object(environment(), break_string(
+     "Du fuehlst, wie der Trank wie Feuer durch Deinen Koerper schiesst "
+     "und kruemmst Dich vor Schmerzen. Doch Momente spaeter laesst die "
+     "Tortur nach.",78));
+
+  // max. 40 Giftlevel heilen...
+  prot_poison = effekt / 50;
+
+  if (prot_poison < 0)
+  {
+    tell_object(environment(), BS(
+      "Bah! Der Trank schmeckt widerlich bitter. Wenn der mal nicht "
+      "giftig war."));
+    call_out(#'ticktack, 5, effekt, 1); // 1 => Gift
+    return 1;
+  }
+  
+  // ab jetzt nur noch positive Wirkungen.
+
+  // P_POISON zuerst.
+  int poison = environment()->QueryProp(P_POISON);
+  if (poison)
+  {
+    if (poison <= prot_poison)
+    {
+      prot_poison -= poison;
+      environment()->SetProp(P_POISON,0);
+      if (!environment()->QueryProp(P_POISON))
+        ++erfolgreich;
+    }
+    else
+    {
+      poison -= prot_poison;
+      prot_poison=0;
+      environment()->SetProp(P_POISON, poison);
+      // Wenn erfolgreich, direkt Meldung und raus.
+      if (environment()->QueryProp(P_POISON) == poison)
+      {
+        tell_object(environment(), break_string(
+           "Ueberrascht stellst Du fest, dass Du Dich "
+           "besser fuehlst - der Trank hat Deine Vergiftung offenbar "
+           "gelindert.",78));
+        return 1;
+      }
+    }
+  }
+
+  // wenn Trank immer noch positiv (also noch WIrkung uebrig)
+  if (prot_poison > 0)
+  {
+    // Als naechstes Objekte suchen.
+    object *ob = filter_objects(all_inventory(environment()),
+                                "is_class_member", CL_POISON);
+    foreach(object o: ob)
+    {
+      // Entgiften kostet ein Zehntel des Levels, aber min. 1.
+      poison = o->QueryProp(P_LEVEL);
+      if (poison <= prot_poison*10)
+      {
+        prot_poison -= poison/10 + 1;
+        o->SetProp(P_LEVEL, 0);
+        if (o->remove())
+          ++erfolgreich;
+      }
+      else
+      {
+        poison -= prot_poison * 10;
+        prot_poison = 0;
+        o->SetProp(P_LEVEL, poison);
+        if (o->QueryProp(P_LEVEL) == poison)
+          ++erfolgreich;
+      }
+      if (prot_poison <= 0)
+        break;
+    }
+  }
+
+  if (erfolgreich)
+  {
+    tell_object(environment(), break_string(
+      "Ueberrascht stellst Du fest, dass Du Dich viel besser fuehlst - der "
+      "Trank wirkt offenbar gegen Vergiftungen.",78));
+  }
+  else
+  {
+    tell_object(environment(), break_string(
+      "Eine Ahnung sagt Dir, dass der Trank irgendeine positive "
+      "Wirkung hat."));
+  }
+
+  // ggf. an die Hooks registrieren, wenn noch Schutzwirkung uebrig ist.
+  if (prot_poison > 0)
+  {
+    // Rueckgabewerte von HRegisterToHook speichern...
+    int *res = ({ reg_hook(H_HOOK_POISON, H_DATA_MODIFICATOR) });
+    res += ({ reg_hook(H_HOOK_INSERT, H_HOOK_MODIFICATOR) });
+    // Wenn alle versuchten Registrierungen erfolgreich waren...? Ansonsten
+    // andere Meldung... Ich bin noch nicht gluecklich, das hier so explizit
+    // auszugeben, aber ich weiss gerade sonst nicht, wie man drauf kommen
+    // soll, dass es ein Problem gibt.
+    if (sizeof(res) == sizeof(res & ({1})))
+      tell_object(environment(),
+         "Vielleicht haelt diese Wirkung ja sogar noch etwas an?\n");
+    else
+    {
+      // zumindest ein erfolg?
+      if (member(res, 1) > -1)
+        tell_object(environment(),
+            "Vielleicht haelt ein Teil dieser Wirkung ja sogar noch etwas an?\n");
+    }
+  }
+  return 1;
+}
+
+private int act_attr_heal_disease(int effekt)
+{
+  int erfolgreich;
+
+  // max. 40 Krankheitslevel heilen...
+  prot_disease = effekt / 50;
+
+  if (prot_disease > 0)
+  {
+     tell_object(environment(), break_string(
+       "Du fuehlst, wie der Trank in Deinem Bauch eine wohlige Waerme "
+       "verbreitet und laechelst unwillkuerlich.",78));
+   
+    // Objekte suchen.
+    object *ob = filter_objects(all_inventory(environment()),
+                                "is_class_member", CL_DISEASE);
+    foreach(object o: ob)
+    {
+      // Heilen kostet ein Fuenftel des Levels, aber min. 1.
+      int disease = o->QueryProp(P_LEVEL);
+      if (disease <= prot_disease*5)
+      {
+        prot_disease -= disease/5 + 1;
+        o->SetProp(P_LEVEL, 0);
+        if (o->remove())
+          ++erfolgreich;
+      }
+      else
+      {
+        disease -= prot_disease * 5;
+        prot_disease = 0;
+        o->SetProp(P_LEVEL, disease);
+        if (o->QueryProp(P_LEVEL) == disease)
+          ++erfolgreich;
+      }
+      if (prot_disease <= 0)
+        break;
+    }
+  }
+  else
+  {
+    tell_object(environment(), BS(
+      "Der Trank schmeckt eklig faulig. Dein Magen rebelliert umgehend. "
+      "Du kannst Deinen Brechreiz gerade noch unterdruecken, fuehlst "
+      "Dich aber krank."));
+    call_out(#'ticktack, 5, effekt, 0); // 0 => Krankheit
+    return 1;
+  }
+
+  if (erfolgreich)
+  {
+    tell_object(environment(), break_string(
+      "Entspannt durchatmend stellst Du fest, dass Du Dich viel besser fuehlst - der "
+      "Trank wirkt offenbar gegen Krankheiten.",78));
+  }
+  else
+  {
+    tell_object(environment(), break_string(
+      "Eine Ahnung sagt Dir, dass der Trank irgendeine positive "
+      "Wirkung hat."));
+  }
+
+  // ggf. an die Hooks registrieren.
+  if (prot_disease > 0)
+  {
+    // Registrierung erfolgreich...? Ansonsten andere Meldung... Ich bin
+    // noch nicht gluecklich, das hier so explizit auszugeben, aber ich
+    // weiss gerade sonst nicht, wie man drauf kommen soll, dass es ein
+    // Problem gibt.
+    if (reg_hook(H_HOOK_INSERT, H_HOOK_MODIFICATOR)==1)
+      tell_object(environment(),
+         "Vielleicht haelt diese Wirkung ja sogar noch etwas an?\n");
+
+  }
+  return 1;
+}
+
+private string num2desc_fight(int bumms)
+{
+  switch(abs(bumms))
+  {
+    case 0..499:
+      return "ein wenig";
+    case 500..999:
+      return "spuerbar";
+    case 1000..1499:
+      return "deutlich";
+    case 1500..2000:
+      return "erheblich";
+  }
+  return "ungenehmigt viel"; // kommt hoffentlich nicht vor.
+}
+
+// AN: Tiere sind: CL_ANIMAL, CL_FISH, CL_FROG, CL_INSECT, CL_MAMMAL,
+// CL_MAMMAL_LAND, CL_MAMMAL_WATER, CL_REPTILE, CL_ARACHNID, CL_BIRD
+private int act_attr_dam_animals(int effekt)
+{
+  if (reg_hook(H_HOOK_ATTACK_MOD, H_DATA_MODIFICATOR) == 1)
+  {
+    if (!mappingp(att_classes)) att_classes=m_allocate(1);
+    att_classes[CL_ANIMAL] = effekt/20;
+    tell_object(environment(), break_string(
+        "Du spuerst in Dir ein seltsames Verlangen aufsteigen, auf die Jagd "
+        "zu gehen - als wuerde Artemis persoenlich Deine Angriffe "
+        + num2desc_fight(effekt)
+        + " verbessern.",78));
+    return 1;
+  }
+  return 0;
+}
+
+// AN: Magische Wesen sollen sein: CL_ELEMENTAL, CL_ILLUSION, CL_SHADOW
+// CL_DRAGON, CL_DEMON, CL_SHAPECHANGER, CL_HARPY
+private int act_attr_dam_magical(int effekt)
+{
+  if (reg_hook(H_HOOK_ATTACK_MOD, H_DATA_MODIFICATOR) == 1)
+  {
+    if (!mappingp(att_classes)) att_classes=m_allocate(4);
+    att_classes[CL_DRAGON] = att_classes[CL_ELEMENTAL]
+                            = att_classes[CL_SHADOW]
+                            = att_classes[CL_ILLUSION]
+                            = effekt/20;
+    tell_object(environment(), break_string(
+        "Merkwuerdig. Du hast gerade das Gefuehl, als fiele Dir der "
+        "Kampf gegen von Hekate beschenkte Wesen "
+        + num2desc_fight(effekt)
+        + " leichter.",78));
+    return 1;
+  }
+  return 0;
+}
+
+// AN: Untote sollen sein: CL_SKELETON, CL_GHOUL, CL_GHOST, CL_VAMPIRE
+// CL_ZOMBIE, CL_UNDEAD
+// Bloed ist nur, dass CL_UNDEAD alle anderen enthaelt bis auf CL_GHOST.
+// Also lassen wir die Unterscheidung und schrittweise Freischaltung
+// erst einmal sein.
+private int act_attr_dam_undead(int effekt)
+{
+  if (reg_hook(H_HOOK_ATTACK_MOD, H_DATA_MODIFICATOR) == 1)
+  {
+    // Zombies, Skelette, Ghule...
+    if (!mappingp(att_classes)) att_classes=m_allocate(1);
+    att_classes[CL_UNDEAD] =  effekt/20;
+    tell_object(environment(), break_string(
+        "Auf einmal hast Du den Eindruck, dass die Kreaturen des "
+        "Hades Deinen Angriffen "
+        + num2desc_fight(effekt)
+        + " weniger entgegen zu setzen haben.",78));
+    return 1;
+  }
+  return 0;
+}
+
+private int act_attr_prot_animals(int effekt)
+{
+  if (reg_hook(H_HOOK_DEFEND, H_DATA_MODIFICATOR) == 1)
+  {
+    if (!mappingp(prot_classes)) prot_classes=m_allocate(1);
+    prot_classes[CL_ANIMAL] = effekt/20;
+    tell_object(environment(), break_string(
+        "Du hast das Gefuehl, dass Artemis ihre schuetzende Hand "
+        + num2desc_fight(effekt)
+        + " ueber Dich haelt.",78));
+    return 1;
+  }
+  return 0;
+}
+
+private int act_attr_prot_magical(int effekt)
+{
+  if (reg_hook(H_HOOK_DEFEND, H_DATA_MODIFICATOR) == 1)
+  {
+    if (!mappingp(prot_classes)) prot_classes=m_allocate(4);
+    prot_classes[CL_DRAGON] = prot_classes[CL_ELEMENTAL]
+                            = prot_classes[CL_SHADOW]
+                            = prot_classes[CL_ILLUSION]
+                            = effekt/20;
+    tell_object(environment(), break_string(
+        "Du hast das Gefuehl, dass von Hekate beschenkte Wesenheiten Dir "
+        +num2desc_fight(effekt)
+        + " weniger anhaben koennen.",78));
+    return 1;
+  }
+  return 0;
+}
+
+private int act_attr_prot_undead(int effekt)
+{
+  if (reg_hook(H_HOOK_DEFEND, H_DATA_MODIFICATOR) == 1)
+  {
+    // Zombies, Skelette, Ghule...
+    if (!mappingp(prot_classes)) prot_classes=m_allocate(1);
+    prot_classes[CL_UNDEAD] =  effekt/20;
+    tell_object(environment(), break_string(
+        "Du bist ploetzlich zuversichtlich, Angriffen der Kreaturen "
+        "des Hades "
+        + num2desc_fight(effekt)
+        + " besser widerstehen zu koennen.",78));
+    return 1;
+  }
+  return 0;
+}
+
+
+private int act_attr_tragen(int effekt)
+{
+  if ( IS_LEARNER(environment()) )
+    tell_object(environment(), sprintf("effekt: %d\n",effekt));
+  SetProp(P_WEIGHT, QueryProp(P_WEIGHT) - effekt*4);
+  tell_object(environment(),
+      BS("Du fuehlst Dich ploetzlich "+num2desc(effekt)
+        + (effekt>0 ? " entlastet" : " belastet") + "."));
+  return 1;
+}
+
+// Berechnet eine max. Verzoegerung der Wirkung abhaengig von der Wirkung und
+// einer Wirkschwelle. Der rel. Abstand von der Wirkschwelle (relativ zum max.
+// moeglichen Abstand) wird hierbei genutzt. Ausserdem ist die max.
+// Verzoegerung natuerlich die Wirkungsdauer des Trankes.
+// <duration> muss im Trank schon gesetzt sein.
+private int calc_max_delay(int effekt, int wirkschwelle)
+{
+  int abstand = abs(effekt - wirkschwelle);
+  if (!duration) duration = time()+600;
+  if ( IS_LEARNER(environment()) )
+    printf("calc_max_delay: %d\n",((duration-time()) * abstand) /
+      (2000-abs(wirkschwelle)));
+  return ((duration-time()) * abstand) / (2000-abs(wirkschwelle));
+}
+
+//TODO: die Zeitverzoegerung ist nen netter Effekt, aber zeitvergzoegerte
+//Tports sind oefter keine gute Idee -> noch pruefen
+//TODO: Die Zeitverzoegerung bei NO_TPORT_OUT auch nochmal pruefen
+private int act_attr_flee_tport(int effekt)
+{
+  // effekt > 0 teleportiert sofort zu halbwegs sicheren Orten
+  // -750 <= effekt < 0 teleportiert auch sofort zu nicht so dollen Orten
+  // -2000 <= effekt < -750 teleportiert spaeter zu bloeden Orten
+  if (effekt < -750 && effekt >= -2000)
+  {
+    // Verzoegerung ausrechnen und dies hier per call_out nochmal mit einem
+    // effekt rufen, der eine instantane Reaktion ausloest.
+    // effekt - 2000 ist ein Hack, damit nicht nochmal verzoegert wird.
+    call_out(#'act_attr_flee_tport,
+        random(calc_max_delay(effekt, -750))+1, effekt - 2000);
+    tell_object(environment(),
+        "Deine Umgebung fuehlt sich nach und nach unwirklicher an.\n");
+    return 1;
+  }
+
+  // Effekte instantan ausloesen.
+
+  // wenn hier kein P_NO_TPORT erlaubt ist, mal gucken, ob wir spaeter noch
+  // zeit haben.
+  if (environment(environment())->QueryProp(P_NO_TPORT)==NO_TPORT_OUT)
+  {
+    tell_object(environment(),
+        BS("Irgendetwas haelt Dich an diesem Ort fest."));
+    int delay = duration - time();
+    // wenn noch genug Restzeit, nochmal versuchen, sonst nix machen.
+    if (delay>10)
+    {
+      // AN/TODO: Kann das nicht auch ziemlich lang sein?
+      call_out(#'act_attr_flee_tport, random(delay), effekt);
+    }
+    return 0;
+  }
+
+  // den Hack von oben rueckgaengig machen, wir brauchen den originalen
+  // Effektwert zurueck.
+  if (effekt < -2000)
+    effekt += 2000;
+
+  string* dests;
+  if ( effekt > 0 )
+  {
+    switch(effekt)
+    {
+      case 0..499:
+        dests = ({"/d/inseln/zesstra/vulkanweg/room/r1",
+                  "/d/fernwest/li/xian/lab2/grab2",
+                  "/d/ebene/miril/schloss/heide11",
+                  "/d/polar/alle/room/weg4_15",
+                  "/d/dschungel/arathorn/tempel/room/t4-5",
+                  "/d/anfaenger/arathorn/minitut/room/huette_"+
+                    environment()->query_real_name(),
+                 });
+        break;
+      case 500..749:
+        dests = ({"/d/ebene/bertram/ebene/wasser8",
+                  "/d/ebene/room/gebuesch2_3",
+                  "/d/polar/alle/room/eiswueste/eiswueste[4,6]",
+                 });
+        if (environment()->QueryProp(P_REAL_RACE)!="Dunkelelf")
+          dests += ({"/d/unterwelt/padreic/kneipe/kneipe"});
+        break;
+      case 750..999:
+        dests = ({"/d/gebirge/silvana/cronoertal/room/tf4",
+                  "/d/inseln/schiffe/floss",
+                  "/d/polar/humni/hexen/room/leuchtkammer",
+                  "/d/polar/gabylon/temong/rooms/anlegestelle",
+                 });
+        break;
+      case 1000..1249:
+        dests = ({"/d/fernwest/shinobi/konfu_quest/room/insel4",
+                  "/d/fernwest/ulo/mura/tokoro/haus4",
+                  "/d/ebene/room/Halle/shalle14",
+                 });
+        break;
+      case 1250..1499:
+        dests = ({"/d/gebirge/silvana/cronoertal/room/tf4",
+                  "/gilden/zauberer",
+                  "/d/gebirge/georg/room/w11"
+                 });
+        break;
+      case 1500..1749:
+        dests = ({"/gilden/bierschuettler",
+                  "/gilden/kaempfer",
+                  "/d/wald/gundur/hobbitdorf/schrein",
+                  "/d/vland/morgoth/room/city/rathalle",
+                 });
+        break;
+      default:
+        dests = ({environment()->QueryProp(P_START_HOME)||
+                    environment()->QueryDefaultHome(),
+                  environment()->QueryDefaultHome(),
+                  "/d/ebene/room/PortVain/po_haf2",
+                  "/d/gebirge/room/he3x3",
+                  "/d/ebene/room/huette",
+                 });
+        break;
+    }
+  }
+  else if ( effekt < 0 )
+  {
+    switch(effekt)
+    {
+      case -499..0:
+        dests = ({"/d/polar/bendeigid/rooms/neskaya/neskay12",
+                  "/players/ketos/gl/room/gl1x1",
+                  "/d/inseln/zesstra/vulkanweg/room/r10",
+                  "/d/vland/morgoth/room/kata/ktanke",
+                  "/d/ebene/zardoz/burg/feuerrau",
+                 });
+        break;
+      case -999..-500:
+        dests = ({"/d/ebene/room/Hoehle/hg6",
+                  "/d/gebirge/silvana/warok/room/l3/wa_3x7",
+                  "/d/vland/morgoth/room/kata/xkat03",
+                  "/d/vland/morgoth/room/kata/kata5",
+                  "/d/wald/yoru/ort/dravi/weg5",
+                  "/d/wald/atamur/room/e83",
+                 });
+        break;
+      case -1499..-1000:
+        dests = ({"/d/polar/bendeigid/rooms/pass/pass_e1",
+                  "/d/ebene/room/gebuesch",
+                  "/d/gebirge/silvana/warok/room/l1/wa_1x6",
+                  "/d/vland/morgoth/room/kata/gkat17",
+                  "/d/wald/atamur/room/e12",
+                 });
+        if (environment()->QueryProp(P_REAL_RACE)=="Dunkelelf")
+          dests += ({"/d/unterwelt/padreic/kneipe/kneipe"});
+        break;
+      case -1749..-1500:
+        dests = ({"/d/dschungel/wurzel/t2",
+                  "/d/vland/morgoth/room/kata/ukat26",
+                  "/d/vland/morgoth/room/kata/h12",
+                  "/d/gebirge/boing/sm/l5/m5x2",
+                 });
+        if (environment()->QueryProp(P_GUILD)=="chaos")
+          dests+=({"/gilden/klerus"});
+        break;
+      default:
+        dests = ({"/d/ebene/rochus/room/sp10",
+                  "/d/ebene/rochus/quest_3player/room/schacht10",
+                 });
+        if ( IS_SEER(environment()) )
+          dests += ({"/d/wald/paracelsus/froom/sch_6e",
+                     "/d/wald/paracelsus/froom/sch_9x",
+                     "/d/wald/paracelsus/froom/sch2_6d",
+                    });
+        break;
+    }
+  }
+  tell_object(environment(),
+      BS("Eine Kraft zerrt an Dir, die Welt verschwimmt..."));
+  if (environment()->move(dests[random(sizeof(dests))],M_TPORT) == MOVE_OK)
+    tell_object(environment(),
+        "Einen Moment spaeter bist Du ganz woanders.\n");
+  else
+    tell_object(environment(),
+        "Aber sonst passiert nichts.\n");
+  return 1;
+}
+
+private int act_attr_change_dimension(int effekt)
+{
+  // nur effekt >= 1000 aendern die Dimension instantan. ;-)
+  if (effekt > 0 && effekt < 1000)
+  {
+    // Verzoegerung ausrechnen und dies hier per call_out nochmal mit einem
+    // effekt rufen, der eine instantane Reaktion ausloest.
+    call_out(#'act_attr_change_dimension,
+        random(calc_max_delay(effekt,1000))+1, 1000);
+    tell_object(environment(),BS("Um Dich herum wird alles "
+        "langsam grauer.\n"));
+    return 1;
+  }
+  // nur -600 < effekt < 0 aendern die Dimension instantan ;-)
+  if (effekt < -600)
+  {
+    // Verzoegerung ausrechnen und dies hier per call_out nochmal mit einem
+    // effekt rufen, der eine instantane Reaktion ausloest.
+    call_out(#'act_attr_change_dimension,
+        random(calc_max_delay(effekt, -600))+1, -601);
+    tell_object(environment(),BS("Um Dich herum wird alles "
+        "langsam grauer.\n"));
+    return 1;
+  }
+  // Effekte instantan ausloesen.
+  // wenn hier kein Para-Trans erlaubt ist, mal gucken, ob wir spaeter noch
+  // zeit haben.
+  if (environment(environment())->QueryProp(P_NO_PARA_TRANS))
+  {
+    int delay = duration - time();
+    // wenn noch genug Restzeit, nochmal versuchen, sonst nix machen.
+    if (delay>10)
+    {
+      call_out(#'act_attr_change_dimension, random(delay), effekt);
+      tell_object(environment(), BS("Die Welt um Dich wird ein "
+            "wenig grauer."));
+    }
+    return 0;
+  }
+  if ( effekt > 0 )
+  {
+    if ( environment()->QueryProp(P_PARA) > 0 )
+    {
+      environment()->SetProp(P_PARA, 0);
+      tell_object(environment(), BS("Fuer einen kurzen Moment siehst Du nur "
+          "ein graues Wabern um Dich herum, bevor die Welt wieder "
+          "normal aussieht.\n"));
+    }
+    else
+    {
+      tell_object(environment(), BS("Fuer einen kurzen Moment sieht alles um "
+            "Dich herum grau aus."));
+    }
+  }
+  else if ( effekt < 0 )
+  {
+    if ( !environment()->QueryProp(P_PARA) )
+    {
+      environment()->SetProp(P_PARA, 1);
+       tell_object(environment(), BS("Fuer einen kurzen Moment siehst Du nur "
+          "ein graues Wabern um Dich herum, bevor die Welt wieder "
+          "normal aussieht. Aber es bleibt ein ungutes Gefuehl.\n"));
+    }
+    else {
+      tell_object(environment(), BS("Fuer einen kurzen Moment sieht alles um "
+            "Dich herum grau aus."));
+    }
+  }
+  return 1;
+}
+
+private int act_attr_defrog(int effekt)
+{
+  // nur effekt > 1000 entfroscht instantan. ;-)
+  if (effekt > 0 && effekt < 1000)
+  {
+    // Verzoegerung ausrechnen und dies hier per call_out nochmal mit einem
+    // effekt rufen, der eine instantane Reaktion ausloest.
+    call_out(#'act_attr_defrog, random(calc_max_delay(effekt,1000))+1, 1000);
+    tell_object(environment(),BS(
+        "Du hoerst ploetzlich lautes Gequake, was langsam immer leiser "
+        "wird.\n"));
+    return 1;
+  }
+  // nur -500 < effekt < 0 froscht instantan ;-)
+  if (effekt < -500)
+  {
+    // Verzoegerung ausrechnen und dies hier per call_out nochmal mit einem
+    // effekt rufen, der eine instantane Reaktion ausloest.
+    call_out(#'act_attr_defrog, random(calc_max_delay(effekt, -500))+1, -501);
+    tell_object(environment(),BS(
+        "Du hoerst ploetzlich ganz leisess Gequake, was langsam immer lauter "
+        "wird.\n"));
+    return 1;
+  }
+
+  // Effekte instantan ausloesen.
+  if ( effekt > 0 )
+  {
+    if ( environment()->QueryProp(P_FROG) )
+    {
+      environment()->SetProp(P_FROG,0);
+      tell_object(PL, "Du fuehlst Dich deutlich weniger gruen.\n");
+    }
+    else
+    {
+      tell_object(environment(), break_string("Die Welt um Dich herum verliert "
+        "ploetzlich alle gruenen Farbtoene, die bald darauf allmaehlich "
+        "zurueckkehren.",78));
+    }
+  }
+  else if ( effekt < 0 ) {
+    if ( !environment()->QueryProp(P_FROG) ) {
+      environment()->SetProp(P_FROG, 1);
+      tell_object(environment(), "Quak!\n");
+    }
+    else {
+      tell_object(environment(), break_string("Deine Sicht verschwimmt, alles wird "
+        "intensiv gruen. Merkwuerdig. Zum Glueck ist das schnell wieder "
+        "vorbei.",78));
+    }
+  }
+  return 1;
+}
+
+private int act_attr_heal_lp(int effekt)
+{
+  if (effekt > 0)
+  {
+    tell_object(environment(),
+        BS("Du fuehlst Dich schlagartig "+num2desc(effekt)
+          + " besser."));
+    environment()->restore_hit_points(effekt/10);
+  }
+  else
+  {
+    tell_object(environment(),
+        BS("Du fuehlst Dich schlagartig "+num2desc(effekt)
+          + " schlechter."));
+    environment()->do_damage(-effekt/10);
+  }
+  return 1;
+}
+
+private int act_attr_heal_sp(int effekt)
+{
+  if (effekt > 0)
+  {
+    tell_object(environment(),
+        BS("Du fuehlst Dich schlagartig "+num2desc(effekt)
+          + " konzentrierter."));
+    environment()->restore_spell_points(effekt/10);
+  }
+  else
+  {
+    tell_object(environment(),
+        BS("Du fuehlst Dich schlagartig "+num2desc(effekt)
+          + " unkonzentrierter."));
+    environment()->reduce_spell_points(-effekt/10);
+  }
+  return 1;
+}
+
+
+private int modify_sa(string sa, int effekt)
+{
+  string msg;
+  switch (sa)
+  {
+    case SA_SPEED:
+      msg = "Du wirst gerade " + num2desc(effekt)
+            +(effekt>0 ? " schneller." : " langsamer.");
+      effekt = (effekt * 30) / 2000;
+      break;
+    case SA_DURATION:
+      msg = "Du wirst gerade " + num2desc(effekt)
+            +(effekt>0 ? " ausdauernder."
+                       : " weniger ausdauernd.");
+      effekt = (effekt * 25) / 2000;
+      break;
+    case SA_SPELL_PENETRATION:
+      msg = "Deine geistige Durchsetzungskraft hat sich gerade "
+            + num2desc(effekt)
+            +(effekt>0 ? " verbessert." : " verschlechtert.");
+      effekt = (effekt * 30) / 2000;
+      break;
+  }
+  if (environment()->ModifySkillAttribute(sa, effekt, duration-time()) ==
+        SA_MOD_OK)
+  {
+    tell_object(environment(),BS(msg));
+    return 1;
+  }
+  return 0;
+}
+
+private int act_attr_change_sa_speed(int effekt)
+{
+  return modify_sa(SA_SPEED, effekt);
+}
+private int act_attr_change_sa_duration(int effekt)
+{
+  return modify_sa(SA_DURATION, effekt);
+}
+private int act_attr_change_sa_spell_penetration(int effekt)
+{
+  return modify_sa(SA_SPELL_PENETRATION, effekt);
+}
+
+
+// Spieler MUSS das environment() sein!
+private void effekt()
+{
+  // Als erstes die Wirkungsdauer verwursten, einige Effekte brauchen
+  // <duration>.
+  // Wann laufen die Effekte denn spaetenstens ab?
+  duration = time() + data[T_EFFECT_DURATION];
+  call_out(#'terminate_effects, data[T_EFFECT_DURATION]);
+
+  // nur echte wirkungen beruecksichtigen, keine "Metadaten"
+  mapping effects = data & T_KRAUT_EFFECTS;
+  // fuer Spieler wird der Paratrans nicht stattfinden.
+  if (!IS_SEER(environment()))
+    m_delete(data, T_CHANGE_DIMENSION);
+
+  // Waehrend der Wirkung ist dieses Objekt schonmal unsichtbar.
+  SetProp(P_INVIS, 1);
+  // Gewicht nullen, bevor die Wirkungen aktiviert werden, da die
+  // Wirkung von T_CARRY ansonsten wieder deaktiviert wuerde. 
+  SetProp(P_WEIGHT, 0);
+  // neue, leere Flasche ins Inventar des Spielers bewegen.
+  clone_object(TRANKITEM)->move(environment(),M_NOCHECK|M_SILENT);
+
+  // auftrennen in positive und negative Effekte. Keys mit Wert 0 werden
+  // ignoriert.
+  mapping peff = filter(effects, function int (string k, int val)
+                        {return val > 0;});
+  mapping neff = filter(effects, function int (string k, int val)
+                        {return val < 0;});
+  // erst die positiven, dann die negativen Wirkungen aktivieren
+  // fuer jede Wirkung wird eine lfun act_<trankattribut>() gerufen, z.B.
+  // act_attr_tragen() (-> act_T_CARRY() )
+  mapping notactivated =
+          filter(peff, function int (string k, int val)
+              {return !funcall(symbol_function("act_"+k,this_object()), val);})
+         +
+          filter(neff, function int (string k, int val)
+              {return !funcall(symbol_function("act_"+k,this_object()), val);});
+  // Meldungen ausgeben ueber nicht aktivierte Wirkungen?
+  // TODO
+}
+
+static int cmd_trinken(string str, mixed *param)
+{
+  if (environment(this_object()) != PL)
+  {
+    write("Aus auf dem Boden liegende Flaschen trinkt es sich so "
+       "schlecht!\n");
+  }
+  else if (data==0)
+  {
+    write("Die Flasche ist leer, Du muesstest erst etwas hineinfuellen.\n");
+  }
+  else if (time()>expiry) 
+  {
+    write(BS("Irgendwie passiert nichts. Hattest Du vielleicht doch nur "
+      "klares Wasser abgefuellt?"));
+    data=0;
+  }
+  else {
+    // Die Sperrzeit muss hier separat berechnet werden, weil eine
+    // Anpassung der Wirkungsdauer im Krautmaster dazu fuehren wuerde,
+    // dass es keine instantan wirkenden Traenke mehr gaebe.
+    int blocktime = max(60+random(60), data[T_EFFECT_DURATION]);
+    if(environment()->check_and_update_timed_key(blocktime, DRINK_POTION)==-1)
+    {
+      write(BS("Du oeffnest die Flasche und trinkst ihren Inhalt aus."));
+      say(BS(PL->Name(WER, 0)+" oeffnet eine Flasche und trinkt sie in einem "
+        "Schluck aus."));
+      effekt();
+      // TODO: reicht das hier aus, oder muss das noch an anderen Stellen 
+      // eingebaut werden?
+      RemoveId(({"trank","kraeutertrank"}));
+    }
+    else {
+      tell_object(environment(), BS(
+        "Der letzte Trank wirkt noch ein wenig nach. Du kannst Deinem "
+        "Magen nicht so bald schon den naechsten zumuten."));
+    }
+  }
+  return 1;
+}
+
+public nomask int Fill(object *plants)
+{
+  if (!pointerp(plants)) return -1;
+  if (data) return -2;  // schon voll
+  data = PLANTMASTER->make_potion(plants);
+  AddId(({"trank","kraeutertrank"}));
+  if (mappingp(data))
+  {
+    // Pflanzen zerstoert der Master, wenns geklappt hat.
+    expiry=time()+data[T_EXPIRE];
+    SetProp(P_WEIGHT, 300);
+    return 1;
+  }
+  return -3;
+}
+
+void NotifyPlayerDeath(object vic, object killer, int exp)
+{
+  call_out("remove",1);
+}
