blob: 23d8caa51d7f4df6591da61bd0ff5b2a4d323989 [file] [log] [blame]
// 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;
}
}