Example #1
0
static dbref
parse_linkable_dest(int descr, dbref player, dbref exit, const char *dest_name)
{
    dbref dobj;        /* destination room/player/thing/link */
    char buf[BUFFER_LEN];
    struct match_data md;

    init_match(descr, player, dest_name, NOTYPE, &md);
    match_absolute(&md);
    match_everything(&md);
    match_home(&md);
    match_null(&md);

    if ((dobj = match_result(&md)) == NOTHING || dobj == AMBIGUOUS) {
        sprintf(buf, CINFO "I couldn't find '%s'.", dest_name);
        anotify_nolisten2(player, buf);
        return NOTHING;

    }

    if (!tp_teleport_to_player && Typeof(dobj) == TYPE_PLAYER) {
        sprintf(buf,
                CFAIL "You can't link to players.  Destination %s ignored.",
                unparse_object(player, dobj));
        anotify_nolisten2(player, buf);
        return NOTHING;
    }

    if (!can_link(player, exit)) {
        anotify_nolisten2(player, CFAIL "You can't link that.");
        return NOTHING;
    }

    if (!can_link_to(player, Typeof(exit), dobj)) {
        sprintf(buf, CFAIL "You can't link to %s.",
                unparse_object(player, dobj));
        anotify_nolisten2(player, buf);
        return NOTHING;
    } else
        return dobj;
}
Example #2
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;
}
Example #3
0
File: wiz.c Project: hyena/fuzzball
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;
}