MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame^] | 1 | // MorgenGrauen MUDlib |
| 2 | // |
| 3 | // shells/magier.c -- magier shell |
| 4 | // |
| 5 | // $Id: magier.c 9231 2015-05-27 21:53:32Z Zesstra $ |
| 6 | |
| 7 | // |
| 8 | // Magiershell Basisfile |
| 9 | // |
| 10 | // Ueberarbeitung abgeschlossen am 18.12.2002 |
| 11 | // |
| 12 | // Dank an Zwirch@PK, Rikus@MG, Zoran@PK, Vanion@MG |
| 13 | // und viele andere, die ich vergessen habe. |
| 14 | // |
| 15 | // Fragen und Bughinweise an Mandragon@MG oder einen |
| 16 | // Erzmagier Deiner Wahl. |
| 17 | // |
| 18 | // Zur Shell gehoeren ausser dieser Datei: |
| 19 | // admin.c: Administrative Befehle |
| 20 | // comm.c: Kommunikationsbefehle |
| 21 | // fileedit.c: Befehle zum Veraendern von Dateien |
| 22 | // fileview.c: Befehle zum Lesen von Dateien |
| 23 | // magier_ext.c: Generelle Magierbefehle |
| 24 | // moving.c: Bewegungsbefehle |
| 25 | // objects.c: Erzeugen und zerstoeren von Objekten |
| 26 | // parsing.c Auswertung von Pfadangaben und Wildcards |
| 27 | // players.c: Befehle zur Beeinflussung von Spielern |
| 28 | // todo.c: Implementation der Todoliste |
| 29 | // upd.c: Der Befehl upd |
| 30 | // magier.h Generelle Header-Datei |
| 31 | // |
| 32 | |
| 33 | #pragma strict_types,save_types |
| 34 | |
| 35 | inherit "/std/player/base"; |
| 36 | inherit "/std/shells/magier/magier_ext"; |
| 37 | |
| 38 | #include <wizlevels.h> |
| 39 | #include <moving.h> |
| 40 | #include <properties.h> |
| 41 | #include <new_skills.h> |
| 42 | #include <config.h> |
| 43 | |
| 44 | protected void create() |
| 45 | { |
| 46 | if (!clonep() || object_name(this_object()) == __FILE__[0..<3]) { |
| 47 | set_next_reset(-1); |
| 48 | return; |
| 49 | } |
| 50 | |
| 51 | base::create(); |
| 52 | |
| 53 | Set(P_RACE, SAVE, F_MODE); |
| 54 | Set(P_ZAP_MSG, SAVE, F_MODE); |
| 55 | Set(P_TRANK_FINDEN, SAVE, F_MODE); |
| 56 | Set(P_HANDS, SAVE, F_MODE); |
| 57 | Set(P_RACESTRING, SAVE, F_MODE); |
| 58 | SetDefaultHome("/gilden/abenteurer"); |
| 59 | SetProp(P_ENEMY_DEATH_SEQUENCE, |
| 60 | ([17:"Der Tod schuettelt verstaendnislos den Kopf.\n\n", |
| 61 | 18:"Der Tod sagt: WIESO MUSSTEST DU DICH AUCH UNBEDINGT " |
| 62 | "MIT EINEM MAGIER ANLEGEN?\n\n"])); |
| 63 | SetProp(P_ATTRIBUTES_OFFSETS,([])); |
| 64 | SetProp(P_AVERAGE_SIZE,185); |
| 65 | if(!QueryProp(P_DEFAULT_GUILD)) SetProp(P_DEFAULT_GUILD,"abenteurer"); |
| 66 | } |
| 67 | |
| 68 | protected void create_super() { |
| 69 | set_next_reset(-1); |
| 70 | } |
| 71 | |
| 72 | |
| 73 | protected void heart_beat() |
| 74 | { |
| 75 | mixed *en; |
| 76 | |
| 77 | if (!QueryProp(P_WANTS_TO_LEARN)||((en=QueryEnemies())&&sizeof(en[0]))) |
| 78 | base::heart_beat(); |
| 79 | else if (!CheckTelnetKeepAlive()) { |
| 80 | // Wenn der Magier kein Telnet Keep-Alive wuenscht, kann der HB ganz |
| 81 | // abgeschaltet werden. Sonst muss er aber weiterlaufen, damit |
| 82 | // CheckTelnetKeepAlive() regelmaessig gerufen wird. |
| 83 | set_heart_beat(0); |
| 84 | } |
| 85 | } |
| 86 | |
| 87 | |
| 88 | public varargs int remove(int silent) |
| 89 | { |
| 90 | string workroom; |
| 91 | |
| 92 | if (IS_WIZARD(this_object())) |
| 93 | workroom = "/players/"+getuid()+"/workroom"; |
| 94 | else |
| 95 | workroom = "/secure/merlin"; |
| 96 | if( !environment() || object_name(environment()) != workroom ) |
| 97 | catch(move(workroom, M_GO, "nach Hause")); |
| 98 | return base::remove(silent); |
| 99 | } |
| 100 | |
| 101 | public string NotifyDestruct(object caller) { |
| 102 | |
| 103 | if (previous_object() != master() |
| 104 | || object_name(this_object()) == __FILE__[..<3]) |
| 105 | return 0; |
| 106 | |
| 107 | // Nicht-EMs sollen keine EMs zerstoeren koennen, woraufhin auch evtl. |
| 108 | // EM-Tools rumliegen koennten. |
| 109 | if ( IS_ARCH(this_object()) && caller != this_object() |
| 110 | && getuid(caller) != ROOTID |
| 111 | && (process_call() || !ARCH_SECURITY) ) |
| 112 | return "Das Zerstoeren von EMs ist ein Fehler. ;-)\n"; |
| 113 | |
| 114 | return ::NotifyDestruct(caller); |
| 115 | } |
| 116 | |
| 117 | void reset() |
| 118 | { |
| 119 | if (!interactive(this_object())) |
| 120 | { |
| 121 | quit(); |
| 122 | if (this_object()) |
| 123 | remove(); |
| 124 | if (this_object()) |
| 125 | destruct(this_object()); |
| 126 | return; |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | // #################### |
| 131 | //################# Query-Funktionen ################## |
| 132 | // #################### |
| 133 | |
| 134 | varargs int id (string str) { |
| 135 | if (QueryProp(P_INVIS) && |
| 136 | (!this_interactive() ||!IS_LEARNER(this_interactive()))) |
| 137 | return 0; |
| 138 | return ::id(str); |
| 139 | } |
| 140 | |
| 141 | |
| 142 | static string *_query_racestring() |
| 143 | { |
| 144 | if (pointerp(Query(P_RACESTRING))) |
| 145 | return Query(P_RACESTRING); |
| 146 | else |
| 147 | return |
| 148 | ({QueryProp(P_RACE),QueryProp(P_RACE), |
| 149 | QueryProp(P_RACE),QueryProp(P_RACE)}); |
| 150 | } |
| 151 | |
| 152 | |
| 153 | static string _query_default_guild() |
| 154 | { |
| 155 | return (Query(P_DEFAULT_GUILD)||"abenteurer"); |
| 156 | } |
| 157 | |
| 158 | |
| 159 | static string _query_racedescr() |
| 160 | { |
| 161 | return "Magier koennen einfach alles. Aber manche Magier koennen mehr.\n"; |
| 162 | } |
| 163 | |
| 164 | |
| 165 | static string _query_race() |
| 166 | { |
| 167 | if (previous_object() && previous_object()->query_login_object()) |
| 168 | return 0; |
| 169 | |
| 170 | return Query(P_RACE) ? Query(P_RACE) : Set(P_RACE, "Magier"); |
| 171 | } |
| 172 | |
| 173 | |
| 174 | static mixed _query_localcmds() |
| 175 | { |
| 176 | return |
| 177 | base::_query_localcmds() |
| 178 | +magier_ext::_query_localcmds(); |
| 179 | } |
| 180 | |
| 181 | |
| 182 | static void upd_my_age() |
| 183 | { |
| 184 | age=_age+absolute_hb_count()-_hbstop; |
| 185 | _age=age; |
| 186 | _hbstop=absolute_hb_count(); |
| 187 | return; |
| 188 | } |
| 189 | |
| 190 | |
| 191 | static int _query_age() |
| 192 | { |
| 193 | upd_my_age(); |
| 194 | return age; |
| 195 | } |
| 196 | |
| 197 | static int _set_earmuffs(int level) |
| 198 | { |
| 199 | int maxl=1+query_wiz_level(this_object()); |
| 200 | maxl = max(maxl,99); |
| 201 | return Set(P_EARMUFFS,min(maxl,level)); |
| 202 | } |
| 203 | |
| 204 | |
| 205 | // ############################ |
| 206 | //#################### Interne Shell-Funktionen #################### |
| 207 | // ############################ |
| 208 | |
| 209 | int MayAddWeight(int w) { return 0;} |
| 210 | int MayAddObject(object ob) { return 1; } |
| 211 | |
| 212 | |
| 213 | static void initialize() |
| 214 | { |
| 215 | magier_ext::initialize(); |
| 216 | return; |
| 217 | } |
| 218 | |
| 219 | |
| 220 | static void FinalSetup() |
| 221 | { |
| 222 | SetProp(P_CURRENTDIR,"/players/"+getuid()); |
| 223 | initialize(); |
| 224 | if (IS_LEARNER(this_player())) cat("/etc/WIZNEWS"); |
| 225 | _age=age; |
| 226 | _hbstop=absolute_hb_count(); |
| 227 | return; |
| 228 | } |
| 229 | |
| 230 | |
| 231 | void save_me(int i) |
| 232 | { |
| 233 | upd_my_age(); |
| 234 | base::save_me(i); |
| 235 | return; |
| 236 | } |
| 237 | |
| 238 | |
| 239 | varargs void Reconnect(int silent,string my_ip) |
| 240 | { |
| 241 | base::Reconnect(silent,my_ip); |
| 242 | magier_ext::reconnect(); |
| 243 | return; |
| 244 | } |
| 245 | |
| 246 | |
| 247 | void notify_player_change(string who, int rein, int invis) |
| 248 | { |
| 249 | string *list,name; |
| 250 | mixed mlist; |
| 251 | int vis_change; |
| 252 | |
| 253 | if (invis) name="("+who+")"; |
| 254 | else name=who; |
| 255 | |
| 256 | if(query_verb() && (query_verb()=="vis" || query_verb()=="invis")) |
| 257 | vis_change=1; |
| 258 | |
| 259 | if (Query(P_INFORMME) && !vis_change) |
| 260 | { |
| 261 | if (rein) |
| 262 | tell_object(this_object(), |
| 263 | sprintf("%s ist gerade ins "MUDNAME" gekommen.\n",name)); |
| 264 | else |
| 265 | tell_object(this_object(), |
| 266 | sprintf("%s hat gerade das "MUDNAME" verlassen.\n",name)); |
| 267 | } |
| 268 | |
| 269 | if(Query(P_WAITFOR_FLAGS) & (0x01))return ; |
| 270 | |
| 271 | if (pointerp(list=Query(P_WAITFOR))&&sizeof(list)) |
| 272 | if (member(list,who)!=-1) |
| 273 | delayed_write( |
| 274 | ({ |
| 275 | ({sprintf("%s%s I S T J E T Z T %s !!!\n", |
| 276 | (QueryProp(P_VISUALBELL) ? "" : sprintf("%c",7)), |
| 277 | name, |
| 278 | (vis_change? |
| 279 | (rein?"S I C H T B A R":"U N S I C H T B A R"): |
| 280 | (rein?"D A":"N I C H T M E H R D A"))), |
| 281 | 0}) |
| 282 | })); |
| 283 | |
| 284 | if (rein && (sizeof(mlist=QueryProp(P_WAITFOR_REASON))) && |
| 285 | (mappingp(mlist)) && (mlist[who])) |
| 286 | Show_WaitFor_Reason(who,invis); |
| 287 | return; |
| 288 | } |
| 289 | |
| 290 | mixed modify_command(string str) { |
| 291 | if (previous_object() && |
| 292 | (previous_object()!=this_object() || process_call()) ) |
| 293 | { |
| 294 | if (IS_ARCH(this_object())) |
| 295 | tell_object(this_object(), |
| 296 | sprintf("Illegal modify_command(%s) from %O\n", |
| 297 | str, previous_object())); |
| 298 | return 0; |
| 299 | } |
| 300 | ////////////////////////////////////////////////////////////////////// |
| 301 | // Magier-Escape-Kommandos werden behandelt |
| 302 | if (str=="\\ESCAPE" && IS_LORD(this_object())) |
| 303 | { |
| 304 | __set_environment(this_object(),"/room/void"); |
| 305 | environment()->init(); |
| 306 | printf("You escaped.\n"); |
| 307 | return ""; |
| 308 | } |
| 309 | if (str[0..2]=="\\\\\\" && IS_LORD(this_object())) |
| 310 | { |
| 311 | str = _return_args(str); |
| 312 | string* input = explode(str[3..]," "); |
| 313 | string verb = input[0]; |
| 314 | if (verb && verb!="") |
| 315 | { |
| 316 | string cmd = implode(input[1..]," "); |
| 317 | if (!__auswerten(cmd,verb)) |
| 318 | SoulComm(cmd,verb); |
| 319 | } |
| 320 | return 1; |
| 321 | } |
| 322 | ////////////////////////////////////////////////////////////////////// |
| 323 | |
| 324 | return ::modify_command(str); |
| 325 | } |
| 326 | |