Added public files

Roughly added all public files. Probably missed some, though.
diff --git a/secure/dropmaster.c b/secure/dropmaster.c
new file mode 100644
index 0000000..dcd09c1
--- /dev/null
+++ b/secure/dropmaster.c
@@ -0,0 +1,202 @@
+#pragma strict_types,save_types,rtt_checks
+#pragma pedantic,range_check
+#pragma no_inherit,no_clone
+#pragma no_shadow
+
+#define _NEED_DROPMASTER_IMPLEMENTATION_
+#include <dropmaster.h>
+#include <defines.h>
+#include <wizlevels.h>
+
+struct random_event_s {
+  string *names;
+  int reduction;
+  int *rnd_values;
+  int *default_rnd_values;
+  string creator;
+};
+
+// Mapping mit einem random_event_s als Wert pro Schluessel
+// Schluessel: 0: globaler Eintrag, ansonsten BP-Namen oder Teile von Pfaden
+// (/d/<eben>/<magier>/<gebiet>/)
+private mapping randomEvents;
+
+private struct random_event_s SanitizeRE(struct random_event_s re)
+{
+    // rnd_values, default_rnd_values und names muessen gleich lang sein -> auf
+    // das kuerzeste kuerzen. Achtung: macht implizit eine Kopie - WICHTIG!
+    int size = sizeof(re->rnd_values);
+    if (pointerp(re->names))
+        size = min(size, sizeof(re->names));
+    if (pointerp(re->default_rnd_values)) {
+      size = min(size, sizeof(re->default_rnd_values));
+      re->default_rnd_values = re->default_rnd_values[0..size-1];
+    }
+    if (pointerp(re->names))
+      re->names = re->names[0..size-1];
+
+    re->rnd_values = re->rnd_values[0..size-1];
+
+    return re;
+}
+
+// key==0 signifies the global key
+public varargs void CreateRandomEvent(string key, int *rnd_val, 
+                                      string *rnd_names, int red)
+{
+  struct random_event_s re = (<random_event_s>);
+  
+  if (!member(randomEvents,key)) {
+    re->rnd_values = copy(rnd_val) || DFLT_RND_VALUES;
+    // wenn rnd_val == 0 ist, ist das OK, dann wird spaeter immer
+    // DFLT_RND_VALUES genommen.
+    re->default_rnd_values = copy(rnd_val);
+    // names darf auch 0 sein, wenn Defaultwerte genommen werden sollen.
+    re->names = copy(rnd_names);
+    re->reduction = red || RND_REDUCTION;
+    re->creator = object_name(extern_call() ? previous_object() : this_object());
+
+    randomEvents[key] = SanitizeRE(re);
+  }
+}
+
+public varargs int ChangeRandomEvent(string key, int *rnd_val, int *rnd_val_dflt, 
+                                      string *rnd_names, int red)
+{
+  if (process_call()) return -1;
+  if (!member(randomEvents, key)) return -2;
+  struct random_event_s re = randomEvents[key];
+  // Schreibzugriff erlauben? Nur fuer Erschafferobjekte und EM.
+  // Bemerkung: RM+ haben Zugriff, weil sie Schreibzugriff auf das
+  // Erschafferobjekt haben.
+  if (extern_call()
+      && re->creator != object_name(previous_object())
+      && !ARCH_SECURITY)
+    return -1;
+
+  if (pointerp(rnd_val))
+    re->rnd_values = rnd_val;
+  if (pointerp(rnd_val_dflt))
+    re->default_rnd_values = rnd_val_dflt;
+  if (pointerp(rnd_names))
+    re->names = rnd_names;
+  if (red)
+    re->reduction = red;
+
+  SanitizeRE(re);
+
+  return 1;
+}
+
+public int DeleteRandomEvent(string key)
+{
+  if (process_call()) return -1;
+  if (!member(randomEvents, key)) return -2;
+  struct random_event_s re = randomEvents[key];
+  // Schreibzugriff erlauben? Nur fuer Erschafferobjekte und EM.
+  // Bemerkung: RMs haben Zugriff, weil sie Schreibzugriff auf das
+  // Erschafferobjekt haben.
+  if (extern_call()
+      && re->creator != object_name(previous_object())
+      && !ARCH_SECURITY)
+    return -1;
+
+  m_delete(randomEvents, key);
+  return 1;
+}
+
+void create()
+{
+  seteuid(getuid(this_object()));
+  restore_object(DROPSAVE);
+  if(!randomEvents || !mappingp(randomEvents))
+  {
+    randomEvents = ([]);
+  }
+  if (!member(randomEvents, GLOBAL_KEY))
+    CreateRandomEvent(GLOBAL_KEY, DFLT_RND_VALUES, DFLT_RND_NAMES, RND_REDUCTION);
+  set_next_reset(3600 + random(10800));
+}
+
+void saveme(){
+  save_object(DROPSAVE);
+}
+
+varargs int remove()
+{
+  saveme();
+  destruct(ME);
+  return 1;
+}
+
+public varargs int dropRare(int rarelevel, string key) {
+  if (!member(randomEvents, key))
+    return 0;
+  
+  struct random_event_s re = randomEvents[key];
+  if (rarelevel < 0 || rarelevel >= sizeof(re->rnd_values))
+    return 0;
+  if (random(re->rnd_values[rarelevel]) == 0)
+  {
+    // Defaultwert wiederherstellen.
+    if (pointerp(re->default_rnd_values))
+      re->rnd_values[rarelevel] = re->default_rnd_values[rarelevel];
+    else
+      re->rnd_values[rarelevel] = DFLT_RND_VALUES[rarelevel];
+    // und droppen.
+    return 1;
+  }
+  else
+  {
+    // Wahrscheinlichkeit erhoehen, indem rnd_values reduziert wird.
+    re->rnd_values[rarelevel] -= re->reduction;
+    // negative rnd_values sind ok, random() ist dann immer 0.
+  }
+  // fall-through
+  return 0;
+}
+
+// Droppt genau 1 oder 0 Items aus dem gegebenen Set. Benutzt hierbei das
+// mittels <key> definierte Randomevent und den zur jeweiligen ID gegebenen
+// <rarelevel>.
+// <set> muss in der Form
+// { {ID,RARELEVEL}, {ID,RARELEVEL}, ... }
+// gegeben werden. <ID> muss dabei != 0 sein und wird im Erfolgsfall
+// zurueckgeben.
+mixed dropSetItem(mixed set, string key) {
+  
+  if (pointerp(set))
+  {
+    set=filter(set, function int (mixed el) {
+      return pointerp(el) && sizeof(el)>=2 && intp(el[1]);
+    } );
+    set=sort_array(set, function int (mixed a, mixed b) {
+      return a[1]>b[1];
+    });
+    
+    foreach(mixed el: set) {
+      if(dropRare(el[1], key)){
+        return el[0];
+      }
+    }      
+  }
+  
+  return 0;
+}
+
+void reset()
+{
+  set_next_reset(3600*72);
+  // ein wenig aufraeumen
+
+  // Alle Events rauswerfen, deren Erschafferobjekt nicht mehr exisiert
+  // (Nachteil: nicht-geladene VC-Objekte werden nicht beruecksichtigt).
+  foreach(string key, struct random_event_s re: randomEvents) {
+    if (!find_object(re->creator)
+        && file_size(re->creator + ".c") <= 0)
+      m_delete(randomEvents, key);
+  }
+
+  saveme();
+}
+