blob: 7e76a11a2731e1925ae8855b08c844aebc225502 [file] [log] [blame]
// MorgenGrauen MUDlib
//
// secure/master/destruct.inc -- module of the master object: stuff for destruct.
//
// $Id: master.c 7041 2008-10-13 18:18:27Z Zesstra $
#include "/sys/object_info.h"
// privilegierte Objekte, die das destruct() abbrechen duerfen (root objekte
// duerfen auch ohne, dass sie in dieser Liste erfasst sind):
private nosave string *deny_destruct_list = ({
"/obj/shut", "/room/void", "/room/netztot", "/room/jail" });
// Helferfunktion fuer prepare_destruct()
private void recursive_remove(object ob, int immediate_destruct) {
if (efun::object_info(ob, OI_ONCE_INTERACTIVE)) {
// Spieler werden ins Void bewegt.
int res;
tell_object(ob, "Ploetzlich loest sich deine Welt in ihre " +
"Bestandteile auf. Zum Glueck wirst\nDu irgendwo " +
"hin geschleudert ...\n");
// wenn Bewegung buggt oder nicht funktioniert und ob noch existiert,
// rekursiv zerstoeren.
object oldenv=environment(ob);
if ( (catch(res=(int)ob->move("/room/void",M_TPORT|M_NOCHECK,0,"faellt");
publish) || (ob && environment(ob) == oldenv) )
&& ob) {
// Spieler speichern, dann erst Inventar entleeren, dann remove() und
// und destruct() anwenden.
catch(ob->save_me(1); publish);
filter(all_inventory(ob), #'recursive_remove, immediate_destruct);
if (!immediate_destruct)
catch(ob->remove(0);publish);
if (ob)
destruct(ob);
}
}
else {
// kein Spieler. Rekursiv entfernen. Hierbei _zuerst_ rekursiv das
// Inventar entfernen und dann ob selber, damit nicht erst das Inventar in
// das Environment bewegt wird (soll ja eh zerstoert werden).
filter(all_inventory(ob), #'recursive_remove, immediate_destruct);
// ggf. zuerst remove versuchen
if (!immediate_destruct)
catch(ob->remove(1);publish);
if (ob)
destruct(ob);
}
}
// Zerstoerung von ob vorbereiten
protected mixed prepare_destruct(object ob)
{
object old_env,env,item;
mixed res;
// zuerst das notify_destruct() rufen und ggf. abbrechen, falls ob
// privilegiert ist.
catch(res = (mixed)ob->NotifyDestruct(previous_object()); publish);
if (res &&
(getuid(ob) == ROOTID ||
(IS_ARCH(ob)) ||
member(deny_destruct_list, object_name(ob)) >= 0)) {
if (stringp(res) && sizeof(res))
return res;
else
return sprintf("%O verweigert die Zerstoerung mittels destruct(). "
"Fehlende Rechte von %O?\n",ob, previous_object());
}
env = environment(ob);
// Objekt hat kein Env: Alles zerstoeren, Spieler ins Void
if (!env) {
filter(all_inventory(ob), #'recursive_remove, 1);
}
else {
// Ansonsten alles ins Environment
foreach(item : all_inventory(ob))
{
old_env=environment(item);
// M_MOVE_ALL, falls item nen Unitobjekt ist. Sonst clonen die u.U. noch
// wieder nen neues Objekt im alten Env.
if(catch(item->move(env, M_NOCHECK|M_MOVE_ALL);publish))
recursive_remove(item, 1);
else if (item && environment(item) == old_env)
recursive_remove(item, 1);
}
}
return 0; // Erfolg
}
// Anmerkung: liefert 0 zurueck, wenn die sefuns gerade geladen werden.
string NotifyDestruct(object caller) {
// Nicht jeder Magier muss den Master entsorgen koennen.
if ((caller != this_object() &&
call_sefun("secure_level") < ARCH_LVL)
|| call_sefun("process_call") ) {
return "Du darfst den Mudlib-Master nicht zerstoeren!\n";
}
return 0;
}