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();
+}
+