Exemple #1
0
void
do_mcpedit(int descr, dbref player, const char *name)
{
    dbref i;
    struct match_data md;
    McpFrame *mfr;

    if (!(mfr = descr_mcpframe(descr))) {
        do_edit(descr, player, name);
        return;
    } else if (Typeof(player) != TYPE_PLAYER) {
        anotify_nolisten2(player, CFAIL "Only players can edit programs.");
        return;
    } else if (!Mucker(player)) {
        anotify_nolisten2(player, CFAIL NOMBIT_MESG);
        return;
    } else if (tp_db_readonly) {
        anotify_nolisten2(player, CFAIL DBRO_MESG);
        return;
    } else if (!*name) {
        anotify_nolisten2(player, CINFO "No program name given.");
        return;
    }

    init_match(descr, player, name, TYPE_PROGRAM, &md);
    match_possession(&md);
    match_neighbor(&md);
    match_registered(&md);
    match_absolute(&md);

    if ((i = noisy_match_result(&md)) == NOTHING || i == AMBIGUOUS)
        return;

    mcpedit_program(descr, player, i, name, mfr);
}
Exemple #2
0
/*
  Use this to create a program.
  First, find a program that matches that name.  If there's one,
  then we put him into edit mode and do it.
  Otherwise, we create a new object for him, and call it a program.
  */
void
do_prog(int descr, dbref player, const char *name)
{
    dbref i;
    struct match_data md;

    if (Typeof(player) != TYPE_PLAYER) {
        anotify_nolisten2(player, CFAIL "Only players can edit programs.");
        return;
    } else if (!Mucker(player)) {
        anotify_nolisten2(player, CFAIL NOMBIT_MESG);
        return;
    } else if (!tp_building || tp_db_readonly) {
        anotify_nolisten2(player, CFAIL NOBUILD_MESG);
        return;
    } else if (!*name) {
        anotify_nolisten2(player, CINFO "No program name given.");
        return;
    }

    init_match(descr, player, name, TYPE_PROGRAM, &md);
    match_possession(&md);
    match_neighbor(&md);
    match_registered(&md);
    match_absolute(&md);

    if ((i = match_result(&md)) == NOTHING) {
        i = new_program(OWNER(player), name);
        FLAGS(i) |= INTERNAL;
        DBFETCH(player)->sp.player.curr_prog = i;

        anotify_fmt(player, CSUCC "Program %s created with number %d.", name,
                    i);
        anotify_nolisten2(player, CINFO "Entering editor.");
    } else if (i == AMBIGUOUS) {
        anotify_nolisten2(player, CINFO "I don't know which one you mean!");
        return;
    } else {
        if ((Typeof(i) != TYPE_PROGRAM) || !controls(player, i)) {
            anotify_fmt(player, CFAIL "%s", tp_noperm_mesg);
            return;
        } else if (FLAGS(i) & INTERNAL) {
            anotify_nolisten2(player, CFAIL NOEDIT_MESG);
            return;
        }

        DBFETCH(i)->sp.program.first = read_program(i);
        FLAGS(i) |= INTERNAL;
        DBFETCH(player)->sp.player.curr_prog = i;
        anotify_fmt(player, CINFO "Entering editor for %s.",
                    unparse_object(player, i));
        /* list current line */
        do_list(player, i, 0, 0, 0);
        DBDIRTY(i);
    }

    FLAGS(player) |= INTERACTIVE;
    DBDIRTY(player);
}
Exemple #3
0
dbref
mesg_dbref_raw(int descr, dbref player, dbref what, dbref perms, const char *buf)
{
	struct match_data md;
	dbref obj = UNKNOWN;

	if (buf && *buf) {
		if (!string_compare(buf, "this")) {
			obj = what;
		} else if (!string_compare(buf, "me")) {
			obj = player;
		} else if (!string_compare(buf, "here")) {
			obj = getloc(player);
		} else if (!string_compare(buf, "home")) {
			obj = HOME;
		} else {
			init_match(descr, player, buf, NOTYPE, &md);
			match_absolute(&md);
			match_all_exits(&md);
			match_neighbor(&md);
			match_possession(&md);
			match_registered(&md);
			obj = match_result(&md);
			if (obj == NOTHING) {
				init_match_remote(descr, player, what, buf, NOTYPE, &md);
				match_player(&md);
				match_all_exits(&md);
				match_neighbor(&md);
				match_possession(&md);
				match_registered(&md);
				obj = match_result(&md);
			}
		}
	}

	if (obj < 0 || obj >= db_top || Typeof(obj) == TYPE_GARBAGE)
		obj = UNKNOWN;
	return obj;
}
Exemple #4
0
void
do_edit(int descr, dbref player, const char *name)
{
    dbref i;
    struct match_data md;

    if (Typeof(player) != TYPE_PLAYER) {
        anotify_nolisten2(player, CFAIL "Only players can edit programs.");
        return;
    } else if (!Mucker(player)) {
        anotify_nolisten2(player, CFAIL NOMBIT_MESG);
        return;
    } else if (tp_db_readonly) {
        anotify_nolisten2(player, CFAIL DBRO_MESG);
        return;
    } else if (!*name) {
        anotify_nolisten2(player, CINFO "No program name given.");
        return;
    }

    init_match(descr, player, name, TYPE_PROGRAM, &md);
    match_possession(&md);
    match_neighbor(&md);
    match_registered(&md);
    match_absolute(&md);

    if ((i = noisy_match_result(&md)) == NOTHING || i == AMBIGUOUS)
        return;

    if ((Typeof(i) != TYPE_PROGRAM) || !controls(player, i)) {
        anotify_fmt(player, CFAIL "%s", tp_noperm_mesg);
        return;
    } else if (FLAGS(i) & INTERNAL) {
        anotify_nolisten2(player, CFAIL NOEDIT_MESG);
        return;
    }

    FLAGS(i) |= INTERNAL;
    DBFETCH(i)->sp.program.first = read_program(i);
    DBFETCH(player)->sp.player.curr_prog = i;
    anotify_fmt(player, CINFO "Entering editor for %s.",
                unparse_object(player, i));
    /* list current line */
    do_list(player, i, 0, 0, 0);
    FLAGS(player) |= INTERACTIVE;
    DBDIRTY(i);
    DBDIRTY(player);
}
Exemple #5
0
void do_give(dbref player, dbref cause, int key, char *who, char *amnt)
{
  dbref	recipient;

	/* check recipient */

	init_match(player, who, TYPE_PLAYER);
	match_neighbor();
	match_possession();
	match_me();
	if (Privilaged(player) || HasPriv(player,NOTHING,POWER_LONG_FINGERS,POWER3,NOTHING)) {
		match_player();
		match_absolute();
	}

	recipient = match_result();
	switch (recipient) {
	case NOTHING:
		notify(player, "Give to whom?");
		return;
	case AMBIGUOUS:
		notify(player, "I don't know who you mean!");
		return;
	}

	if (DePriv(player,recipient,DP_GIVE,POWER7,POWER_LEVEL_SPC)) {
		notify(player, "Permission denied.");
		return;
	}
	if (DePriv(recipient,player,DP_RECEIVE,POWER7,POWER_LEVEL_SPC)) {
		notify(player, "Permission denied.");
		return;
	}
	if (is_number(amnt)) {
		give_money(player, recipient, key, atoi(amnt));
	} else if(Guest(recipient)) {
		notify(player, "Guest really doesn't need money or anything.");
		return;
	} else {
            if ( Typeof(player) != TYPE_ROOM )
		give_thing(player, recipient, key, amnt);
            else
                notify(player, "Command incompatible with invoker type.");
	}
}
Exemple #6
0
/*
 * parse_source()
 *
 * This is a utility used by do_action and do_attach.  It parses
 * the source string into a dbref, and checks to see that it
 * exists.
 *
 * The return value is the dbref of the source, or NOTHING if an
 * error occurs.
 *
 */
dbref
parse_source(int descr, dbref player, const char *source_name)
{
    dbref source;
    struct match_data md;

    init_match(descr, player, source_name, NOTYPE, &md); /* source type can be
                                                          * any */
    match_neighbor(&md);
    match_me(&md);
    match_here(&md);
    match_possession(&md);
    match_registered(&md);
    match_absolute(&md);
    source = noisy_match_result(&md);

    if (source == NOTHING)
        return NOTHING;

    /* You can only attach actions to things you control */
    if (!controls(player, source)) {
        anotify_fmt(player, CFAIL "%s", tp_noperm_mesg);
        return NOTHING;
    }
    if (Typeof(source) == TYPE_EXIT) {
        anotify_nolisten2(player,
                          CFAIL "You can't attach an action to an action.");
        return NOTHING;
    }
    if (Typeof(source) == TYPE_PROGRAM) {
        anotify_nolisten2(player,
                          CFAIL "You can't attach an action to a program.");
        return NOTHING;
    }
    return source;
}
Exemple #7
0
void
match_and_list(int descr, dbref player, const char *name, char *linespec)
{
	dbref thing;
	char *p;
	char *q;
	int range[2];
	int argc;
	struct match_data md;
	struct line *tmpline;

	init_match(descr, player, name, TYPE_PROGRAM, &md);
	match_neighbor(&md);
	match_possession(&md);
	match_registered(&md);
	match_absolute(&md);
	if ((thing = noisy_match_result(&md)) == NOTHING)
		return;
	if (Typeof(thing) != TYPE_PROGRAM) {
		notify(player, "You can't list anything but a program.");
		return;
	}
/*	if (!(controls(player, thing) || Linkable(thing))) { */
	if (!(controls(player, thing) || (FLAGS(thing) & VEHICLE))) {
		notify(player, "Permission denied. (You don't control the program, and it's not set Viewable)");
		return;
	}
	if (!*linespec) {
		range[0] = 1;
		range[1] = -1;
		argc = 2;
	} else {
		q = p = linespec;
		while (*p) {
			while (*p && !isspace(*p))
				*q++ = *p++;
			while (*p && isspace(*++p)) ;
		}
		*q = '\0';

		argc = 1;
		if (isdigit(*linespec)) {
			range[0] = atoi(linespec);
			while (*linespec && isdigit(*linespec))
				linespec++;
		} else {
			range[0] = 1;
		}
		if (*linespec) {
			argc = 2;
			while (*linespec && !isdigit(*linespec))
				linespec++;
			if (*linespec)
				range[1] = atoi(linespec);
			else
				range[1] = -1;
		}
	}
	tmpline = PROGRAM_FIRST(thing);
	PROGRAM_SET_FIRST(thing, read_program(thing));
	do_list(player, thing, range, argc);
	free_prog_text(PROGRAM_FIRST(thing));
	PROGRAM_SET_FIRST(thing, tmpline);
	return;
}
Exemple #8
0
static void give_thing (dbref giver, dbref recipient, int key, char *what)
{
dbref	thing, loc;
char	*str, *sp;

	init_match(giver, what, TYPE_THING);
	match_possession();
	match_me();
	thing = match_result();

	switch (thing) {
	case NOTHING:
		notify(giver, "You don't have that!");
		return;
	case AMBIGUOUS:
		notify(giver, "I don't know which you mean!");
		return;
	}

	if (thing == giver) {
		notify(giver, "You can't give yourself away!");
		return;
	}

	if (((Typeof(thing) != TYPE_THING) &&
	     (Typeof(thing) != TYPE_PLAYER)) ||
	    !(Enter_ok(recipient) || controls(giver, recipient))) {
		notify(giver, "Permission denied.");
		return;
	}
	if ((Flags3(thing) & NOMOVE) && !Wizard(giver)) {
		notify(giver, "Permission denied.");
		return;
	}

	if (!could_doit(giver, thing, A_LGIVE,1)) {
		sp = str = alloc_lbuf("do_give.gfail");
		safe_str((char *)"You can't give ", str, &sp);
		safe_str(Name(thing), str, &sp);
		safe_str((char *)" away.", str, &sp);
		*sp = '\0';

		did_it(giver, thing, A_GFAIL, str, A_OGFAIL, NULL,
			A_AGFAIL, (char **)NULL, 0);
		free_lbuf(str);
		return;
	}
	if (!could_doit(thing, recipient, A_LRECEIVE,1)) {
		sp = str = alloc_lbuf("do_give.rfail");
		safe_str(Name(recipient), str, &sp);
		safe_str((char *)" doesn't want ", str, &sp);
		safe_str(Name(thing), str, &sp);
		safe_chr('.', str, &sp);
		*sp = '\0';

		did_it(giver, recipient, A_RFAIL, str, A_ORFAIL, NULL,
			A_ARFAIL, (char **)NULL, 0);
		free_lbuf(str);
		return;
	}
	loc = Location(giver);
	if ( !Good_obj(loc) || loc == NOTHING || loc == AMBIGUOUS || Recover(loc) || Going(loc) )
           loc = giver;
	if (!could_doit(giver, loc, A_LGIVETO, 1)) {
		sp = str = alloc_lbuf("do_giveto.rfail");
		safe_str((char *)"You can not give ", str, &sp);
		safe_str(Name(thing), str, &sp);
		safe_str((char *)" away at this location.", str, &sp);
		*sp = '\0';
		notify(giver, str);
		free_lbuf(str);
		return;
	}

	move_via_generic(thing, recipient, giver, 0);
	divest_object(thing);
	
	if (!(key & GIVE_QUIET)) {
		str = alloc_lbuf("do_give.thing.ok");
		strcpy(str, Name(giver));
		notify_with_cause(recipient, giver,
			unsafe_tprintf("%s gave you %s.", str, Name(thing)));
		notify(giver, "Given.");
		notify_with_cause(thing, giver,
			unsafe_tprintf("%s gave you to %s.", str, Name(recipient)));
		free_lbuf(str);
	}
	else {
		notify(giver, "Given. (quiet)");
	}
	did_it(giver, thing, A_DROP, NULL, A_ODROP, NULL, A_ADROP,
		(char **)NULL, 0);
	did_it(recipient, thing, A_SUCC, NULL, A_OSUCC, NULL, A_ASUCC,
		(char **)NULL, 0);
}
Exemple #9
0
/* do_link
 *
 * Use this to link to a room that you own.  It also sets home for
 * objects and things, and drop-to's for rooms.
 * It seizes ownership of an unlinked exit, and costs 1 penny
 * plus a penny transferred to the exit owner if they aren't you
 *
 * All destinations must either be owned by you, or be LINK_OK.
 */
void
do_link(int descr, dbref player, const char *thing_name, const char *dest_name)
{
    dbref good_dest[MAX_LINKS];
    int ndest, i;
    struct match_data md;
    char buf[BUFFER_LEN];
    dbref thing, dest;

    if (tp_db_readonly) {
        anotify_nolisten2(player, CFAIL DBRO_MESG);
        return;
    }

    if (Guest(player)) {
        anotify_fmt(player, CFAIL "%s", tp_noguest_mesg);
        return;
    }

    init_match(descr, player, thing_name, TYPE_EXIT, &md);
    match_all_exits(&md);
    match_neighbor(&md);
    match_possession(&md);
    match_me(&md);
    match_here(&md);
    match_absolute(&md);
    match_registered(&md);

    if (Mage(OWNER(player)))
        match_player(&md);

    if ((thing = noisy_match_result(&md)) == NOTHING)
        return;

    switch (Typeof(thing)) {
        case TYPE_EXIT:
            /* we're ok, check the usual stuff */
            if (DBFETCH(thing)->sp.exit.ndest != 0) {
                if (controls(player, thing)) {
                    if ((DBFETCH(thing)->sp.exit.dest)[0] != NIL) {
                        anotify_nolisten2(player,
                                          CINFO "That exit is already linked.");
                        return;
                    }
                } else {
                    anotify_fmt(player, CFAIL "%s", tp_noperm_mesg);
                    return;
                }
            }

            /* handle costs */
            if (OWNER(thing) == OWNER(player)) {
                if (!payfor(player, tp_link_cost)) {
                    anotify_fmt(player,
                                CFAIL "It costs %d %s to link this exit.",
                                tp_link_cost,
                                (tp_link_cost == 1) ? tp_penny : tp_pennies);
                    return;
                }
            } else {
                if (!payfor(player, tp_link_cost + tp_exit_cost)) {
                    anotify_fmt(player,
                                CFAIL "It costs %d %s to link this exit.",
                                (tp_link_cost + tp_exit_cost),
                                (tp_link_cost + tp_exit_cost ==
                                 1) ? tp_penny : tp_pennies);
                    return;
                } else if (!Builder(player)) {
                    anotify_nolisten2(player, CFAIL NOBBIT_MESG);
                    return;
                } else {
                    /* pay the owner for his loss */
                    dbref owner = OWNER(thing);

                    DBFETCH(owner)->sp.player.pennies += tp_exit_cost;
                    DBDIRTY(owner);
                }
            }

            /* link has been validated and paid for; do it */
            OWNER(thing) = OWNER(player);

            if (!
                (ndest =
                 link_exit(descr, player, thing, (char *) dest_name,
                           good_dest))) {
                anotify_nolisten2(player, CFAIL "No destinations linked.");
                DBFETCH(player)->sp.player.pennies += tp_link_cost; /* Refund! */
                DBDIRTY(player);
                break;
            }

            DBFETCH(thing)->sp.exit.ndest = ndest;
            if (DBFETCH(thing)->sp.exit.dest)
                free(DBFETCH(thing)->sp.exit.dest);

            DBFETCH(thing)->sp.exit.dest =
                (dbref *) malloc(sizeof(dbref) * ndest);
            for (i = 0; i < ndest; i++)
                (DBFETCH(thing)->sp.exit.dest)[i] = good_dest[i];
            break;
        case TYPE_THING:
        case TYPE_PLAYER:
            init_match(descr, player, dest_name, TYPE_ROOM, &md);
            match_neighbor(&md);
            match_absolute(&md);
            match_registered(&md);
            match_me(&md);
            match_here(&md);
            match_null(&md);

            if (Typeof(thing) == TYPE_THING)
                match_possession(&md);
            if ((dest = noisy_match_result(&md)) == NOTHING)
                return;
	    if (Typeof(thing) == TYPE_THING && dest == NIL) {
                anotify_fmt(player, CFAIL "%s", "You cannot HOME a THING to NIL.");
                return;		
	    }
            if (!controls(player, thing)
                || !can_link_to(player, Typeof(thing), dest)) {
                anotify_fmt(player, CFAIL "%s", tp_noperm_mesg);
                return;
            }
            if (parent_loop_check(thing, dest)) {
                anotify_nolisten2(player,
                                  CFAIL "That would cause a parent paradox.");
                return;
            }
            /* do the link */
            if (Typeof(thing) == TYPE_THING) {
                DBFETCH(thing)->sp.thing.home = dest;
            } else
                DBFETCH(thing)->sp.player.home = dest;
            sprintf(buf, CSUCC "%s's home set to %s.",
                    NAME(thing), unparse_object(player, dest));
            anotify_nolisten2(player, buf);
            break;
        case TYPE_ROOM:        /* room dropto's */
            init_match(descr, player, dest_name, TYPE_ROOM, &md);
            match_neighbor(&md);
            match_possession(&md);
            match_registered(&md);
            match_absolute(&md);
            match_home(&md);
            match_null(&md);

            if ((dest = noisy_match_result(&md)) == NOTHING)
                break;

            if (!controls(player, thing)
                || !can_link_to(player, Typeof(thing), dest)
                || (thing == dest)) {
                anotify_fmt(player, CFAIL "%s", tp_noperm_mesg);
            } else {
                DBFETCH(thing)->sp.room.dropto = dest; /* dropto */
                sprintf(buf, CSUCC "%s's dropto set to %s.",
                        NAME(thing), unparse_object(player, dest));
                anotify_nolisten2(player, buf);
            }

            break;
        case TYPE_PROGRAM:
            anotify_nolisten2(player,
                              CFAIL "You can't link programs to things!");
            break;
        default:
            anotify_nolisten2(player, CFAIL "Weird object type.");
            log_status("*BUG: weird object: Typeof(%d) = %d\n",
                       thing, Typeof(thing));
            break;
    }
    DBDIRTY(thing);
    return;
}
Exemple #10
0
void
do_force(int descr, dbref player, const char *what, char *command)
{
	dbref victim, loc;
	struct match_data md;

	assert(what != NULL);
	assert(command != NULL);
	assert(player > 0);

	if (force_level > (tp_max_force_level - 1)) {
		notify(player, "Can't force recursively.");
		return;
	}

	if (!tp_zombies && (!Wizard(player) || Typeof(player) != TYPE_PLAYER)) {
		notify(player, "Zombies are not enabled here.");
		return;
#ifdef DEBUG	
	} else {
		notify(player, "[debug] Zombies are not enabled for nonwizards -- force succeeded.");
#endif
	}

	/* get victim */
	init_match(descr, player, what, NOTYPE, &md);
	match_neighbor(&md);
	match_possession(&md);
	match_me(&md);
	match_here(&md);
	match_absolute(&md);
	match_registered(&md);
	match_player(&md);

	if ((victim = noisy_match_result(&md)) == NOTHING) {
#ifdef DEBUG
		notify(player, "[debug] do_force: unable to find your target!");
#endif /* DEBUG */
		return;
	}

	if (Typeof(victim) != TYPE_PLAYER && Typeof(victim) != TYPE_THING) {
		notify(player, "Permission Denied -- Target not a player or thing.");
		return;
	}
#ifdef GOD_PRIV
	if (God(victim)) {
		notify(player, "You cannot force God to do anything.");
		return;
	}
#endif							/* GOD_PRIV */

/*    if (!controls(player, victim)) {
 *	notify(player, "Permission denied. (you're not a wizard!)");
 *	return;
 *    }
 */

	if (!Wizard(player) && !(FLAGS(victim) & XFORCIBLE)) {
		notify(player, "Permission denied: forced object not @set Xforcible.");
		return;
	}
	if (!Wizard(player) && !test_lock_false_default(descr, player, victim, MESGPROP_FLOCK)) {
		notify(player, "Permission denied: Object not force-locked to you.");
		return;
	}

	loc = getloc(victim);
	if (!Wizard(player) && Typeof(victim) == TYPE_THING && loc != NOTHING &&
		(FLAGS(loc) & ZOMBIE) && Typeof(loc) == TYPE_ROOM) {
		notify(player, "Sorry, but that's in a no-puppet zone.");
		return;
	}

	if (!Wizard(OWNER(player)) && Typeof(victim) == TYPE_THING) {
		const char *ptr = NAME(victim);
		char objname[BUFFER_LEN], *ptr2;

		if ((FLAGS(player) & ZOMBIE)) {
			notify(player, "Permission denied -- you cannot use zombies.");
			return;
		}
		if (FLAGS(victim) & DARK) {
			notify(player, "Permission denied -- you cannot force dark zombies.");
			return;
		}
		for (ptr2 = objname; *ptr && !isspace(*ptr);)
			*(ptr2++) = *(ptr++);
		*ptr2 = '\0';
		if (lookup_player(objname) != NOTHING) {
			notify(player, "Puppet cannot share the name of a player.");
			return;
		}
	}

	log_status("FORCED: %s(%d) by %s(%d): %s", NAME(victim),
			   victim, NAME(player), player, command);
	/* force victim to do command */
	force_prog=NOTHING;
	force_level++;
	process_command(dbref_first_descr(victim), victim, command);
	force_level--;
	force_prog=NOTHING;
}
Exemple #11
0
void
do_teleport(int descr, dbref player, const char *arg1, const char *arg2)
{
	dbref victim;
	dbref destination;
	const char *to;
	struct match_data md;

	/* get victim, destination */
	if (*arg2 == '\0') {
		victim = player;
		to = arg1;
	} else {
		init_match(descr, player, arg1, NOTYPE, &md);
		match_neighbor(&md);
		match_possession(&md);
		match_me(&md);
		match_here(&md);
		match_absolute(&md);
		match_registered(&md);
		match_player(&md);

		if ((victim = noisy_match_result(&md)) == NOTHING) {
			return;
		}
		to = arg2;
	}
#ifdef GOD_PRIV
	if(tp_strict_god_priv && !God(player) && God(OWNER(victim))) {
		notify(player, "God has already set that where He wants it to be.");
		return;
	}
#endif

	/* get destination */
	init_match(descr, player, to, TYPE_PLAYER, &md);
	match_possession(&md);
	match_me(&md);
	match_here(&md);
	match_home(&md);
	match_absolute(&md);
	match_registered(&md);
	if (Wizard(OWNER(player))) {
		match_neighbor(&md);
		match_player(&md);
	}
	switch (destination = match_result(&md)) {
	case NOTHING:
		notify(player, "Send it where?");
		break;
	case AMBIGUOUS:
		notify(player, "I don't know which destination you mean!");
		break;
	case HOME:
		switch (Typeof(victim)) {
		case TYPE_PLAYER:
			destination = PLAYER_HOME(victim);
			if (parent_loop_check(victim, destination))
				destination = PLAYER_HOME(OWNER(victim));
			break;
		case TYPE_THING:
			destination = THING_HOME(victim);
			if (parent_loop_check(victim, destination)) {
			  destination = PLAYER_HOME(OWNER(victim));
			  if (parent_loop_check(victim, destination)) {
			    destination = (dbref) 0;
			  }
			}
			break;
		case TYPE_ROOM:
			destination = GLOBAL_ENVIRONMENT;
			break;
		case TYPE_PROGRAM:
			destination = OWNER(victim);
			break;
		default:
			destination = tp_player_start;	/* caught in the next
											   * switch anyway */
			break;
		}
	default:
		switch (Typeof(victim)) {
		case TYPE_PLAYER:
			if (!controls(player, victim) ||
				!controls(player, destination) ||
				!controls(player, getloc(victim)) ||
				(Typeof(destination) == TYPE_THING && !controls(player, getloc(destination)))) {
				notify(player, "Permission denied. (must control victim, dest, victim's loc, and dest's loc)");
				break;
			}
			if (Typeof(destination) != TYPE_ROOM && Typeof(destination) != TYPE_THING) {
				notify(player, "Bad destination.");
				break;
			}
			if (!Wizard(victim) &&
				(Typeof(destination) == TYPE_THING && !(FLAGS(destination) & VEHICLE))) {
				notify(player, "Destination object is not a vehicle.");
				break;
			}
			if (parent_loop_check(victim, destination)) {
				notify(player, "Objects can't contain themselves.");
				break;
			}
			notify(victim, "You feel a wrenching sensation...");
			enter_room(descr, victim, destination, DBFETCH(victim)->location);
			notify(player, "Teleported.");
			break;
		case TYPE_THING:
			if (parent_loop_check(victim, destination)) {
				notify(player, "You can't make a container contain itself!");
				break;
			}
		case TYPE_PROGRAM:
			if (Typeof(destination) != TYPE_ROOM
				&& Typeof(destination) != TYPE_PLAYER && Typeof(destination) != TYPE_THING) {
				notify(player, "Bad destination.");
				break;
			}
			if (!((controls(player, destination) ||
				   can_link_to(player, NOTYPE, destination)) &&
				  (controls(player, victim) || controls(player, DBFETCH(victim)->location)))) {
				notify(player, "Permission denied. (must control dest and be able to link to it, or control dest's loc)");
				break;
			}
			/* check for non-sticky dropto */
			if (Typeof(destination) == TYPE_ROOM
				&& DBFETCH(destination)->sp.room.dropto != NOTHING
				&& !(FLAGS(destination) & STICKY))
						destination = DBFETCH(destination)->sp.room.dropto;
			if (tp_thing_movement && (Typeof(victim) == TYPE_THING)) {
				enter_room(descr, victim, destination, DBFETCH(victim)->location);
			} else {
				moveto(victim, destination);
			}
			notify(player, "Teleported.");
			break;
		case TYPE_ROOM:
			if (Typeof(destination) != TYPE_ROOM) {
				notify(player, "Bad destination.");
				break;
			}
			if (!controls(player, victim)
				|| !can_link_to(player, NOTYPE, destination)
				|| victim == GLOBAL_ENVIRONMENT) {
				notify(player, "Permission denied. (Can't move #0, dest must be linkable, and must control victim)");
				break;
			}
			if (parent_loop_check(victim, destination)) {
				notify(player, "Parent would create a loop.");
				break;
			}
			moveto(victim, destination);
			notify(player, "Parent set.");
			break;
		case TYPE_GARBAGE:
			notify(player, "That object is in a place where magic cannot reach it.");
			break;
		default:
			notify(player, "You can't teleport that.");
			break;
		}
		break;
	}
	return;
}