blob: 23d8caa51d7f4df6591da61bd0ff5b2a4d323989 [file] [log] [blame]
MG Mud User88f12472016-06-24 23:31:02 +02001// MorgenGrauen MUDlib
2//
3// player/potion.c -- potion handling for player
4//
5// $Id: potion.c 9280 2015-08-15 22:20:36Z Arathorn $
6//
7
8#pragma strong_types,save_types
9
10#include <input_to.h>
11
12#define NEED_PROTOTYPES
13#include <thing/properties.h>
14#include <player/potion.h>
15#include <attributes.h>
16#include <living/life.h>
17#include <player/base.h>
18#undef NEED_PROTOTYPES
19
20#include <properties.h>
21#include <defines.h>
22#include <wizlevels.h>
23
24#define POTIONMASTER "/secure/potionmaster"
25
26static mixed *list;
27
28mixed *potionrooms;
29mixed *known_potionrooms;
30
31static mixed _query_potionrooms();
32static mixed _query_known_potionrooms();
33
34protected void create()
35{
36 if (!potionrooms) potionrooms = POTIONMASTER->InitialList();
37 Set(P_POTIONROOMS, NOSETMETHOD, F_SET_METHOD); // no tampering by methods
38 Set(P_POTIONROOMS, SECURED, F_MODE_AS); // no tampering with list
39
40 if (!known_potionrooms) known_potionrooms = ({});
41 Set(P_KNOWN_POTIONROOMS, NOSETMETHOD, F_SET_METHOD);
42 Set(P_KNOWN_POTIONROOMS, SECURED, F_MODE_AS);
43}
44
45static int ReportPotion(string s, int pnum);
46static int SelectWhich(int pnum);
47static int ask_question(int pnum);
48static int get_answer(string erg, int pnum);
49static int raise(string what, int pnum);
50int AddKnownPotion(int nr);
51int RemoveKnownPotion(int nr);
52
53protected void updates_after_restore(int newflag)
54{
55 // P_VISITED_POTIONROOMS ist lang veraltet und unbenutzt, aber bis zum
56 // 21.1.2015 sogar in neuen Spielern gespeichert worden.
57 // Aehnlich fuer P_BONUS_POTIONS. Weg damit.
58 Set(P_VISITED_POTIONROOMS, SAVE|PROTECTED, F_MODE_AD);
59 Set(P_BONUS_POTIONS, SAVE|PROTECTED, F_MODE_AD);
60}
61
62varargs int FindPotion(string s)
63{
64 object po = previous_object();
65 int pnum = POTIONMASTER->HasPotion(po);
66 int flag = 1;
67
68 if ( QueryProp(P_TRANK_FINDEN) && IS_WIZARD(ME) )
69 {
70 return ReportPotion(s, pnum);
71 }
72
73 if ( QueryProp(P_KILLS) )
74 return 0;
75
76 if ( !potionrooms || !sizeof(potionrooms) ||
77 !(POTIONMASTER->InList(po, potionrooms, known_potionrooms)) )
78 flag=0;
79
80 if ( pnum < 0 || !flag )
81 return 0;
82
83 if ( query_input_pending(ME) || query_editing(ME) )
84 {
85 tell_object(ME,
86 "Jetzt haettest Du fast einen Zaubertrank gefunden. Du solltest den\n"
87 "Editor/das More verlassen und es dann noch einmal versuchen!\n");
88 return 1;
89 }
90
91 // Hier der Ausbau der ZTs fuer Geister, wobei das natuerlich in der
92 // Geisterschlossquest immer noch gehen sollte.
93 object env = environment(ME);
94 string fn = old_explode(object_name(env), "#")[0];
95 if ( QueryProp(P_GHOST) && fn[0..24] != "/d/wald/bertram/gschloss/" )
96 {
97 tell_object(ME,"Als Geist einen Zaubertrank? Hier nicht!\n");
98 return 1;
99 }
100 log_file("ARCH/POTIONS", sprintf("%s %s in %s\n", dtime(time()),
101 capitalize(getuid()), object_name(po)));
102
103 return ReportPotion(s, pnum);
104}
105
106static int ReportPotion(string s, int pnum)
107{
108 if (stringp(s) && sizeof(s))
109 tell_object(ME, s);
110 else
111 tell_object(ME, "Du findest einen Zaubertrank, den Du sofort trinkst.\n");
112
113 SelectWhich(pnum);
114
115 return 1;
116}
117
118static int SelectWhich(int pnum)
119{
120 list=({"Intelligenz","Kraft","Geschicklichkeit","Ausdauer"});
121 if (QueryRealAttribute(A_INT)>=20) list-=({"Intelligenz"});
122 if (QueryRealAttribute(A_STR)>=20) list-=({"Kraft"});
123 if (QueryRealAttribute(A_DEX)>=20) list-=({"Geschicklichkeit"});
124 if (QueryRealAttribute(A_CON)>=20) list-=({"Ausdauer"});
125 if (!sizeof(list)) {
126 heal_self(10000000);
127 tell_object(ME, "Der Trank hat Dich geheilt.\n");
128 log_file("ARCH/POTIONS",
129 sprintf(" %s: Heiltrank (noch %d)\n",
130 capitalize(getuid()), sizeof(potionrooms)-1));
131
132 potionrooms -= ({pnum});
133 known_potionrooms -= ({pnum});
134 save_me(1);
135 return 1;
136 }
137 if ( sizeof(list)==1 )
138 return raise(list[0], pnum);
139 ask_question(pnum);
140 return 1;
141}
142
143static int ask_question(int pnum)
144{
145 int i;
146
147 tell_object(ME, "Deine Attribute sehen so aus:\n\n"
148 +sprintf("Intelligenz : %2d (%+d)\n",
149 QueryRealAttribute(A_INT),QueryAttributeOffset(A_INT))
150 +sprintf("Kraft : %2d (%+d)\n",
151 QueryRealAttribute(A_STR),QueryAttributeOffset(A_STR))
152 +sprintf("Geschicklichkeit: %2d (%+d)\n",
153 QueryRealAttribute(A_DEX),QueryAttributeOffset(A_DEX))
154 +sprintf("Ausdauer : %2d (%+d)\n",
155 QueryRealAttribute(A_CON),QueryAttributeOffset(A_CON))
156 );
157
158 tell_object(ME,
159 "\nWas moechtest Du erhoehen? Du hast folgende Moeglichkeiten:\n");
160 for (i=0; i<sizeof(list); i++)
161 tell_object(ME, sprintf("%d) %s\n", i+1, list[i]));
162
163 input_to("get_answer", INPUT_PROMPT,
164 sprintf("\nBitte gib jetzt eine Zahl (1-%d) an: ", i), pnum);
165
166 return 1;
167}
168
169static int get_answer(string erg, int pnum)
170{
171 int num = to_int(erg);
172
173 if ( num > 0 && num <= sizeof(list) )
174 return raise(list[num-1], pnum);
175
176 tell_object(ME, "Deine Wahl war ungueltig. Bitte versuch's nochmal!\n\n");
177 return ask_question(pnum);
178}
179
180static int raise(string what, int pnum) {
181 string attr;
182
183 switch (what)
184 {
185 case "Geschicklichkeit": attr=A_DEX; break;
186 case "Intelligenz": attr=A_INT; break;
187 case "Kraft": attr=A_STR; break;
188 case "Ausdauer": attr=A_CON; break;
189 default: return 0;
190 }
191
192 int yet=QueryRealAttribute(attr);
193 SetRealAttribute(attr, yet+1);
194 tell_object(ME,
195 sprintf("Deine %s hat sich von %d auf %d erhoeht.\n", what, yet, yet+1));
196 log_file("ARCH/POTIONS",
197 sprintf(" %s: %s %d->%d (noch %d)\n",
198 capitalize(getuid()), capitalize(attr),
199 yet, yet+1, sizeof(potionrooms)-1));
200
201 // Wenn die Property gesetzt ist, wird nicht versucht, den gefundenen Trank
202 // aus der ZT-Liste des Magiers auszutragen. Der Nebeneffekt, dass
203 // existierende, angeschlossene ZTs auch nicht mehr aus der ZT-Liste von
204 // testenden Magiern ausgetragen werden, wird dabei in Kauf genommen.
205 if ( !QueryProp(P_TRANK_FINDEN) )
206 {
207 potionrooms -= ({ pnum });
208 known_potionrooms -= ({ pnum });
209 save_me(1);
210 }
211 return 1;
212}
213
214static mixed _query_potionrooms()
215{
216 return copy(Set(P_POTIONROOMS, potionrooms));
217}
218
219static mixed _query_known_potionrooms()
220{
221 return copy(Set(P_KNOWN_POTIONROOMS, known_potionrooms));
222}
223
224int AddKnownPotion(int nr)
225{
226 if (!previous_object() ||
227 object_name(previous_object()) != "/room/orakel")
228 return -1; // Keine Berechtigung
229
230 if (member(known_potionrooms, nr) != -1)
231 return -2; // Nummer bereits eingetragen
232 else
233 {
234 known_potionrooms += ({ nr });
235 return 1;
236 }
237}
238
239int RemoveKnownPotion(int nr)
240{
241 if (!previous_object() ||
242 object_name(previous_object()) != "/room/orakel")
243 return -1; // Keine Berechtigung
244
245 if (member(known_potionrooms, nr) == -1)
246 return -2; // Nummer nicht eingetragen
247 else
248 {
249 known_potionrooms -= ({ nr });
250 return 1;
251 }
252}