Added public files
Roughly added all public files. Probably missed some, though.
diff --git a/std/player/potion.c b/std/player/potion.c
new file mode 100644
index 0000000..23d8caa
--- /dev/null
+++ b/std/player/potion.c
@@ -0,0 +1,252 @@
+// MorgenGrauen MUDlib
+//
+// player/potion.c -- potion handling for player
+//
+// $Id: potion.c 9280 2015-08-15 22:20:36Z Arathorn $
+//
+
+#pragma strong_types,save_types
+
+#include <input_to.h>
+
+#define NEED_PROTOTYPES
+#include <thing/properties.h>
+#include <player/potion.h>
+#include <attributes.h>
+#include <living/life.h>
+#include <player/base.h>
+#undef NEED_PROTOTYPES
+
+#include <properties.h>
+#include <defines.h>
+#include <wizlevels.h>
+
+#define POTIONMASTER "/secure/potionmaster"
+
+static mixed *list;
+
+mixed *potionrooms;
+mixed *known_potionrooms;
+
+static mixed _query_potionrooms();
+static mixed _query_known_potionrooms();
+
+protected void create()
+{
+ if (!potionrooms) potionrooms = POTIONMASTER->InitialList();
+ Set(P_POTIONROOMS, NOSETMETHOD, F_SET_METHOD); // no tampering by methods
+ Set(P_POTIONROOMS, SECURED, F_MODE_AS); // no tampering with list
+
+ if (!known_potionrooms) known_potionrooms = ({});
+ Set(P_KNOWN_POTIONROOMS, NOSETMETHOD, F_SET_METHOD);
+ Set(P_KNOWN_POTIONROOMS, SECURED, F_MODE_AS);
+}
+
+static int ReportPotion(string s, int pnum);
+static int SelectWhich(int pnum);
+static int ask_question(int pnum);
+static int get_answer(string erg, int pnum);
+static int raise(string what, int pnum);
+int AddKnownPotion(int nr);
+int RemoveKnownPotion(int nr);
+
+protected void updates_after_restore(int newflag)
+{
+ // P_VISITED_POTIONROOMS ist lang veraltet und unbenutzt, aber bis zum
+ // 21.1.2015 sogar in neuen Spielern gespeichert worden.
+ // Aehnlich fuer P_BONUS_POTIONS. Weg damit.
+ Set(P_VISITED_POTIONROOMS, SAVE|PROTECTED, F_MODE_AD);
+ Set(P_BONUS_POTIONS, SAVE|PROTECTED, F_MODE_AD);
+}
+
+varargs int FindPotion(string s)
+{
+ object po = previous_object();
+ int pnum = POTIONMASTER->HasPotion(po);
+ int flag = 1;
+
+ if ( QueryProp(P_TRANK_FINDEN) && IS_WIZARD(ME) )
+ {
+ return ReportPotion(s, pnum);
+ }
+
+ if ( QueryProp(P_KILLS) )
+ return 0;
+
+ if ( !potionrooms || !sizeof(potionrooms) ||
+ !(POTIONMASTER->InList(po, potionrooms, known_potionrooms)) )
+ flag=0;
+
+ if ( pnum < 0 || !flag )
+ return 0;
+
+ if ( query_input_pending(ME) || query_editing(ME) )
+ {
+ tell_object(ME,
+ "Jetzt haettest Du fast einen Zaubertrank gefunden. Du solltest den\n"
+ "Editor/das More verlassen und es dann noch einmal versuchen!\n");
+ return 1;
+ }
+
+ // Hier der Ausbau der ZTs fuer Geister, wobei das natuerlich in der
+ // Geisterschlossquest immer noch gehen sollte.
+ object env = environment(ME);
+ string fn = old_explode(object_name(env), "#")[0];
+ if ( QueryProp(P_GHOST) && fn[0..24] != "/d/wald/bertram/gschloss/" )
+ {
+ tell_object(ME,"Als Geist einen Zaubertrank? Hier nicht!\n");
+ return 1;
+ }
+ log_file("ARCH/POTIONS", sprintf("%s %s in %s\n", dtime(time()),
+ capitalize(getuid()), object_name(po)));
+
+ return ReportPotion(s, pnum);
+}
+
+static int ReportPotion(string s, int pnum)
+{
+ if (stringp(s) && sizeof(s))
+ tell_object(ME, s);
+ else
+ tell_object(ME, "Du findest einen Zaubertrank, den Du sofort trinkst.\n");
+
+ SelectWhich(pnum);
+
+ return 1;
+}
+
+static int SelectWhich(int pnum)
+{
+ list=({"Intelligenz","Kraft","Geschicklichkeit","Ausdauer"});
+ if (QueryRealAttribute(A_INT)>=20) list-=({"Intelligenz"});
+ if (QueryRealAttribute(A_STR)>=20) list-=({"Kraft"});
+ if (QueryRealAttribute(A_DEX)>=20) list-=({"Geschicklichkeit"});
+ if (QueryRealAttribute(A_CON)>=20) list-=({"Ausdauer"});
+ if (!sizeof(list)) {
+ heal_self(10000000);
+ tell_object(ME, "Der Trank hat Dich geheilt.\n");
+ log_file("ARCH/POTIONS",
+ sprintf(" %s: Heiltrank (noch %d)\n",
+ capitalize(getuid()), sizeof(potionrooms)-1));
+
+ potionrooms -= ({pnum});
+ known_potionrooms -= ({pnum});
+ save_me(1);
+ return 1;
+ }
+ if ( sizeof(list)==1 )
+ return raise(list[0], pnum);
+ ask_question(pnum);
+ return 1;
+}
+
+static int ask_question(int pnum)
+{
+ int i;
+
+ tell_object(ME, "Deine Attribute sehen so aus:\n\n"
+ +sprintf("Intelligenz : %2d (%+d)\n",
+ QueryRealAttribute(A_INT),QueryAttributeOffset(A_INT))
+ +sprintf("Kraft : %2d (%+d)\n",
+ QueryRealAttribute(A_STR),QueryAttributeOffset(A_STR))
+ +sprintf("Geschicklichkeit: %2d (%+d)\n",
+ QueryRealAttribute(A_DEX),QueryAttributeOffset(A_DEX))
+ +sprintf("Ausdauer : %2d (%+d)\n",
+ QueryRealAttribute(A_CON),QueryAttributeOffset(A_CON))
+ );
+
+ tell_object(ME,
+ "\nWas moechtest Du erhoehen? Du hast folgende Moeglichkeiten:\n");
+ for (i=0; i<sizeof(list); i++)
+ tell_object(ME, sprintf("%d) %s\n", i+1, list[i]));
+
+ input_to("get_answer", INPUT_PROMPT,
+ sprintf("\nBitte gib jetzt eine Zahl (1-%d) an: ", i), pnum);
+
+ return 1;
+}
+
+static int get_answer(string erg, int pnum)
+{
+ int num = to_int(erg);
+
+ if ( num > 0 && num <= sizeof(list) )
+ return raise(list[num-1], pnum);
+
+ tell_object(ME, "Deine Wahl war ungueltig. Bitte versuch's nochmal!\n\n");
+ return ask_question(pnum);
+}
+
+static int raise(string what, int pnum) {
+ string attr;
+
+ switch (what)
+ {
+ case "Geschicklichkeit": attr=A_DEX; break;
+ case "Intelligenz": attr=A_INT; break;
+ case "Kraft": attr=A_STR; break;
+ case "Ausdauer": attr=A_CON; break;
+ default: return 0;
+ }
+
+ int yet=QueryRealAttribute(attr);
+ SetRealAttribute(attr, yet+1);
+ tell_object(ME,
+ sprintf("Deine %s hat sich von %d auf %d erhoeht.\n", what, yet, yet+1));
+ log_file("ARCH/POTIONS",
+ sprintf(" %s: %s %d->%d (noch %d)\n",
+ capitalize(getuid()), capitalize(attr),
+ yet, yet+1, sizeof(potionrooms)-1));
+
+ // Wenn die Property gesetzt ist, wird nicht versucht, den gefundenen Trank
+ // aus der ZT-Liste des Magiers auszutragen. Der Nebeneffekt, dass
+ // existierende, angeschlossene ZTs auch nicht mehr aus der ZT-Liste von
+ // testenden Magiern ausgetragen werden, wird dabei in Kauf genommen.
+ if ( !QueryProp(P_TRANK_FINDEN) )
+ {
+ potionrooms -= ({ pnum });
+ known_potionrooms -= ({ pnum });
+ save_me(1);
+ }
+ return 1;
+}
+
+static mixed _query_potionrooms()
+{
+ return copy(Set(P_POTIONROOMS, potionrooms));
+}
+
+static mixed _query_known_potionrooms()
+{
+ return copy(Set(P_KNOWN_POTIONROOMS, known_potionrooms));
+}
+
+int AddKnownPotion(int nr)
+{
+ if (!previous_object() ||
+ object_name(previous_object()) != "/room/orakel")
+ return -1; // Keine Berechtigung
+
+ if (member(known_potionrooms, nr) != -1)
+ return -2; // Nummer bereits eingetragen
+ else
+ {
+ known_potionrooms += ({ nr });
+ return 1;
+ }
+}
+
+int RemoveKnownPotion(int nr)
+{
+ if (!previous_object() ||
+ object_name(previous_object()) != "/room/orakel")
+ return -1; // Keine Berechtigung
+
+ if (member(known_potionrooms, nr) == -1)
+ return -2; // Nummer nicht eingetragen
+ else
+ {
+ known_potionrooms -= ({ nr });
+ return 1;
+ }
+}