MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame^] | 1 | // 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 | |
| 26 | static mixed *list; |
| 27 | |
| 28 | mixed *potionrooms; |
| 29 | mixed *known_potionrooms; |
| 30 | |
| 31 | static mixed _query_potionrooms(); |
| 32 | static mixed _query_known_potionrooms(); |
| 33 | |
| 34 | protected 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 | |
| 45 | static int ReportPotion(string s, int pnum); |
| 46 | static int SelectWhich(int pnum); |
| 47 | static int ask_question(int pnum); |
| 48 | static int get_answer(string erg, int pnum); |
| 49 | static int raise(string what, int pnum); |
| 50 | int AddKnownPotion(int nr); |
| 51 | int RemoveKnownPotion(int nr); |
| 52 | |
| 53 | protected 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 | |
| 62 | varargs 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 | |
| 106 | static 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 | |
| 118 | static 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 | |
| 143 | static 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 | |
| 169 | static 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 | |
| 180 | static 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 | |
| 214 | static mixed _query_potionrooms() |
| 215 | { |
| 216 | return copy(Set(P_POTIONROOMS, potionrooms)); |
| 217 | } |
| 218 | |
| 219 | static mixed _query_known_potionrooms() |
| 220 | { |
| 221 | return copy(Set(P_KNOWN_POTIONROOMS, known_potionrooms)); |
| 222 | } |
| 223 | |
| 224 | int 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 | |
| 239 | int 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 | } |