Beispiel #1
0
const char *
unparse_object(dbref player, dbref loc)
{
	static char buf[BUFFER_LEN];
	if (player == NOTHING)
		goto islog;
	if (Typeof(player) != TYPE_PLAYER)
		player = OWNER(player);
islog:
	switch (loc) {
	case NOTHING:
		return "*NOTHING*";
	case AMBIGUOUS:
		return "*AMBIGUOUS*";
	case HOME:
		return "*HOME*";
	default:
		if (loc < 0 || loc >= db_top)
			return "*INVALID*";

		if ((player == NOTHING) || (!(FLAGS(player) & STICKY) &&
			(can_link_to(player, NOTYPE, loc) ||
			 ((Typeof(loc) != TYPE_PLAYER) &&
			  (controls_link(player, loc) || (FLAGS(loc) & CHOWN_OK)))))) {
			/* show everything */
			snprintf(buf, sizeof(buf), "%.*s(#%d%s)", (BUFFER_LEN / 2), NAME(loc), loc, unparse_flags(loc));
			return buf;
		} else {
			/* show only the name */
			return NAME(loc);
		}
	}
}
Beispiel #2
0
/* utility for open and link */
static dbref
parse_linkable_room(dbref player, const char *room_name)
{
  dbref room;

  /* parse room */
  if (!strcasecmp(room_name, "here")) {
    room = IsExit(player) ? Source(player) : Location(player);
  } else if (!strcasecmp(room_name, "home")) {
    return HOME;                /* HOME is always linkable */
  } else {
    room = parse_objid(room_name);
  }

  /* check room */
  if (!GoodObject(room)) {
    notify(player, T("That is not a valid object."));
    return NOTHING;
  } else if (Going(room)) {
    notify(player, T("That room is being destroyed. Sorry."));
    return NOTHING;
  } else if (!can_link_to(player, room)) {
    notify(player, T("You can't link to that."));
    return NOTHING;
  } else {
    return room;
  }
}
Beispiel #3
0
const char *
unparse_object(dbref player, dbref loc)
{
    char tbuf[BUFFER_LEN];

    if (Typeof(player) != TYPE_PLAYER)
        player = OWNER(player);
    switch (loc) {
        case NOTHING:
            return "*NOTHING*";
        case AMBIGUOUS:
            return "*AMBIGUOUS*";
        case HOME:
            return "*HOME*";
        case NIL:
            return "*NIL*";
        default:
            if (loc < 0 || loc >= db_top)
#ifdef SANITY
            {
                sprintf(upb, "*INVALID*(#%d)", loc);
                return upb;
            }
#else
                return "*INVALID*";
#endif
#ifndef SANITY
            if (!(FLAGS(player) & STICKY) &&
                (TMage(player) || POWERS(player) & POW_SEE_ALL ||
                 can_link_to(player, NOTYPE, loc) ||
                 controls_link(player, loc) ||
                 ((Typeof(loc) != TYPE_PLAYER) && (FLAGS(loc) & CHOWN_OK))
                )) {
                /* show everything */
#endif
                sprintf(upb, "%s(#%d%s)", NAME(loc), loc,
                        unparse_flags(loc, tbuf));
                return upb;
#ifndef SANITY
            } else {
                /* show only the name */
                return NAME(loc);
            }
#endif
    }
}
const char *
unparse_object(dbref player, dbref loc)
{
    static char buf[BUFFER_LEN];

    if (Typeof(player) != TYPE_PLAYER)
	player = OWNER(player);
    switch (loc) {
	case NOTHING:
	    return "*NOTHING*";
	case AMBIGUOUS:
	    return "*AMBIGUOUS*";
	case HOME:
	    return "*HOME*";
	default:
	    if (loc < 0 || loc > db_top)
#ifdef SANITY
	    {
	        sprintf(buf, "*INVALID*(#%d)", loc);
	        return buf;
	    }
#else
		return "*INVALID*";
#endif
#ifndef SANITY
	    if (!(FLAGS(player) & STICKY) &&
		    (can_link_to(player, NOTYPE, loc) ||
		     ((Typeof(loc) != TYPE_PLAYER) &&
		      (controls_link(player, loc) ||
		       (FLAGS(loc) & CHOWN_OK)))
		    )) {
		/* show everything */
#endif
		sprintf(buf, "%s(#%d%s)", PNAME(loc), loc, unparse_flags(loc));
		return buf;
#ifndef SANITY
	    } else {
		/* show only the name */
		return PNAME(loc);
	    }
#endif
    }
}
Beispiel #5
0
const char *
ansi_unparse_object(dbref player, dbref loc)
{
    char tbuf[BUFFER_LEN], tbuf2[BUFFER_LEN];

    if (Typeof(player) != TYPE_PLAYER)
        player = OWNER(player);
    switch (loc) {
        case NOTHING:
            return SYSNORMAL "*NOTHING*";
        case AMBIGUOUS:
            return SYSPURPLE "*AMBIGUOUS*";
        case HOME:
            return SYSWHITE "*HOME*";
        case NIL:
            return SYSCYAN "*NIL*";
        default:
            if (loc < 0 || loc >= db_top) {
                sprintf(upb, SYSRED "*INVALID(#%d)*", loc);
                return upb;
            }
#ifndef SANITY
            if (!(FLAGS(player) & STICKY) &&
                (TMage(player) || POWERS(player) & POW_SEE_ALL ||
                 POWERS(player) & POW_SEARCH ||
                 can_link_to(player, NOTYPE, loc) ||
                 controls_link(player, loc) ||
                 ((Typeof(loc) != TYPE_PLAYER) && (FLAGS(loc) & CHOWN_OK))
                )) {
#endif
                /* show everything */
                sprintf(upb, "%s" SYSYELLOW "(#%d%s)",
                        ansiname(loc, tbuf), loc, unparse_flags(loc, tbuf2));
                return upb;
#ifndef SANITY
            } else {
                /* show only the name */
                return ansiname(loc, upb);
            }
#endif
    }
}
Beispiel #6
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;
}
Beispiel #7
0
const char *
ansi_unparse_object(dbref player, dbref loc)
{
    char tbuf[BUFFER_LEN], tbuf2[BUFFER_LEN];

    if (Typeof(player) != TYPE_PLAYER)
	player = OWNER(player);
    switch (loc) {
	case NOTHING:
	    return CGLOOM "*NOTHING*";
	case AMBIGUOUS:
	    return CPURPLE "*AMBIGUOUS*";
	case HOME:
	    return CWHITE "*HOME*";
	default:
	    if (!OkObj(loc))
		return CRED "*INVALID*";
#ifndef SANITY
	    if (!(FLAGS(player) & STICKY) &&
		    (TMage(player) ||
		     can_link_to(player, NOTYPE, loc) ||
		     controls_link(player, loc) ||
		     ((Typeof(loc) != TYPE_PLAYER) &&
		     (FLAGS(loc) & CHOWN_OK))
		    )) {
#endif
		/* show everything */
		sprintf(upb, "%s" CYELLOW "(#%d%s)",
		    ansiname(loc, tbuf), loc, unparse_flags(loc, tbuf2));
		return upb;
#ifndef SANITY
	    } else {
		/* show only the name */
		return ansiname(loc, upb);
	    }
#endif
    }
}
Beispiel #8
0
struct frame *
interp(int descr, dbref player, dbref location, dbref program,
	   dbref source, int nosleeps, int whichperms, int forced_pid)
{
	struct frame *fr;
	int i;

	if (!MLevel(program) || !MLevel(OWNER(program)) ||
		((source != NOTHING) && !TrueWizard(OWNER(source)) &&
		 !can_link_to(OWNER(source), TYPE_EXIT, program))) {
		notify_nolisten(player, "Program call: Permission denied.", 1);
		return 0;
	}
	if (free_frames_list) {
		fr = free_frames_list;
		free_frames_list = fr->next;
	} else {
		fr = (struct frame *) malloc(sizeof(struct frame));
	}
	fr->next = NULL;
	fr->pid = forced_pid ? forced_pid : top_pid++;
	fr->descr = descr;
	fr->multitask = nosleeps;
	fr->perms = whichperms;
	fr->already_created = 0;
	fr->been_background = (nosleeps == 2);
	fr->trig = source;
	fr->events = NULL;
	fr->timercount = 0;
	fr->started = time(NULL);
	fr->instcnt = 0;
	fr->skip_declare = 0;
	fr->wantsblanks = 0;
	fr->caller.top = 1;
	fr->caller.st[0] = source;
	fr->caller.st[1] = program;

	fr->system.top = 1;
	fr->system.st[0].progref = 0;
	fr->system.st[0].offset = 0;

	fr->waitees = NULL;
	fr->waiters = NULL;

	fr->fors.top = 0;
	fr->fors.st = NULL;
	fr->trys.top = 0;
	fr->trys.st = NULL;

	fr->errorstr = NULL;
	fr->errorinst = NULL;
	fr->errorprog = NOTHING;
	fr->errorline = 0;

	fr->rndbuf = NULL;
	fr->dlogids = NULL;

	fr->argument.top = 0;
	fr->pc = PROGRAM_START(program);
	fr->writeonly = ((source == -1) || (Typeof(source) == TYPE_ROOM) ||
					 ((Typeof(source) == TYPE_PLAYER) && (!online(source))) ||
					 (FLAGS(player) & READMODE));
	fr->level = 0;
	fr->error.is_flags = 0;

	/* set basic local variables */

	fr->svars = NULL;
	fr->lvars = NULL;
	for (i = 0; i < MAX_VAR; i++) {
		fr->variables[i].type = PROG_INTEGER;
		fr->variables[i].data.number = 0;
	}

	fr->brkpt.force_debugging = 0;
	fr->brkpt.debugging = 0;
	fr->brkpt.bypass = 0;
	fr->brkpt.isread = 0;
	fr->brkpt.showstack = 0;
	fr->brkpt.dosyspop = 0;
	fr->brkpt.lastline = 0;
	fr->brkpt.lastpc = 0;
	fr->brkpt.lastlisted = 0;
	fr->brkpt.lastcmd = NULL;
	fr->brkpt.breaknum = -1;

	fr->brkpt.lastproglisted = NOTHING;
	fr->brkpt.proglines = NULL;

	fr->brkpt.count = 1;
	fr->brkpt.temp[0] = 1;
	fr->brkpt.level[0] = -1;
	fr->brkpt.line[0] = -1;
	fr->brkpt.linecount[0] = -2;
	fr->brkpt.pc[0] = NULL;
	fr->brkpt.pccount[0] = -2;
	fr->brkpt.prog[0] = program;

	fr->proftime.tv_sec = 0;
	fr->proftime.tv_usec = 0;
	fr->totaltime.tv_sec = 0;
	fr->totaltime.tv_usec = 0;

	fr->variables[0].type = PROG_OBJECT;
	fr->variables[0].data.objref = player;
	fr->variables[1].type = PROG_OBJECT;
	fr->variables[1].data.objref = location;
	fr->variables[2].type = PROG_OBJECT;
	fr->variables[2].data.objref = source;
	fr->variables[3].type = PROG_STRING;
	fr->variables[3].data.string = (!*match_cmdname) ? 0 : alloc_prog_string(match_cmdname);

	if (PROGRAM_CODE(program)) {
		PROGRAM_INC_PROF_USES(program);
	}
	PROGRAM_INC_INSTANCES(program);
	push(fr->argument.st, &(fr->argument.top), PROG_STRING, *match_args ?
		 MIPSCAST alloc_prog_string(match_args) : 0);
	return fr;
}
Beispiel #9
0
/** Link an exit, room, player, or thing.
 * \verbatim
 * This is the top-level function for @link, which is used to link an
 * exit to a destination, set a player or thing's home, or set a
 * drop-to on a room.
 *
 * Linking an exit usually seizes ownership of the exit and costs 1 penny.
 * 1 penny is also transferred to the former owner.
 * \endverbatim
 * \param player the enactor.
 * \param name the name of the object to link.
 * \param room_name the name of the link destination.
 * \param preserve if 1, preserve ownership and zone data on exit relink.
 */
void
do_link(dbref player, const char *name, const char *room_name, int preserve)
{
  /* Use this to link to a room that you own.
   * It usually seizes ownership of the exit and costs 1 penny,
   * plus a penny transferred to the exit owner if they aren't you.
   * You must own the linked-to room AND specify it by room number.
   */

  dbref thing;
  dbref room;

  if (!room_name || !*room_name) {
    do_unlink(player, name);
    return;
  }
  if (!IsRoom(player) && GoodObject(Location(player)) &&
      IsExit(Location(player))) {
    notify(player, T("You somehow wound up in a exit. No biscuit."));
    return;
  }
  if ((thing = noisy_match_result(player, name, TYPE_EXIT, MAT_EVERYTHING))
      != NOTHING) {
    switch (Typeof(thing)) {
    case TYPE_EXIT:
      if ((room = check_var_link(room_name)) == NOTHING)
        room = parse_linkable_room(player, room_name);
      if (room == NOTHING)
        return;
      if (GoodObject(room) && !can_link_to(player, room)) {
        notify(player, T("Permission denied."));
        break;
      }
      /* We may link an exit if it's unlinked and we pass the link-lock
       * or if we control it.
       */
      if (!(controls(player, thing)
            || ((Location(thing) == NOTHING)
                && eval_lock(player, thing, Link_Lock)))) {
        notify(player, T("Permission denied."));
        return;
      }
      if (preserve && !Wizard(player)) {
        notify(player, T("Permission denied."));
        return;
      }
      /* handle costs */
      if (Owner(thing) == Owner(player)) {
        if (!payfor(player, LINK_COST)) {
          notify_format(player, T("It costs %d %s to link this exit."),
                        LINK_COST, ((LINK_COST == 1) ? MONEY : MONIES));
          return;
        }
      } else {
        if (!payfor(player, LINK_COST + EXIT_COST)) {
          int a = LINK_COST + EXIT_COST;
          notify_format(player, T("It costs %d %s to link this exit."), a,
                        ((a == 1) ? MONEY : MONIES));
          return;
        } else if (!preserve) {
          /* pay the owner for his loss */
          giveto(Owner(thing), EXIT_COST);
          chown_object(player, thing, player, 0);
        }
      }

      /* link has been validated and paid for; do it */
      if (!preserve) {
        Owner(thing) = Owner(player);
        Zone(thing) = Zone(player);
      }
      Location(thing) = room;

      /* notify the player */
      notify_format(player, T("Linked exit #%d to %s"), thing,
                    unparse_object(player, room));
      break;
    case TYPE_PLAYER:
    case TYPE_THING:
      if ((room =
           noisy_match_result(player, room_name, NOTYPE,
                              MAT_EVERYTHING)) == NOTHING) {
        notify(player, T("No match."));
        return;
      }
      if (IsExit(room)) {
        notify(player, T("That is an exit."));
        return;
      }
      if (thing == room) {
        notify(player, T("You may not link something to itself."));
        return;
      }
      /* abode */
      if (!controls(player, room) && !Abode(room)) {
        notify(player, T("Permission denied."));
        break;
      }
      if (!controls(player, thing)) {
        notify(player, T("Permission denied."));
      } else if (room == HOME) {
        notify(player, T("Can't set home to home."));
      } else {
        /* do the link */
        Home(thing) = room;     /* home */
        if (!Quiet(player) && !(Quiet(thing) && (Owner(thing) == player)))
          notify(player, T("Home set."));
      }
      break;
    case TYPE_ROOM:
      if ((room = parse_linkable_room(player, room_name)) == NOTHING)
        return;
      if ((room != HOME) && (!IsRoom(room))) {
        notify(player, T("That is not a room!"));
        return;
      }
      if (!controls(player, thing)) {
        notify(player, T("Permission denied."));
      } else {
        /* do the link, in location */
        Location(thing) = room; /* dropto */
        notify(player, T("Dropto set."));
      }
      break;
    default:
      notify(player, T("Internal error: weird object type."));
      do_log(LT_ERR, NOTHING, NOTHING,
             "Weird object! Type of #%d is %d", thing, Typeof(thing));
      break;
    }
  }
}
Beispiel #10
0
/*
 * do_dig
 *
 * Use this to create a room.
 */
void
do_dig(int descr, dbref player, const char *name, const char *pname)
{
    char *rname, *qname;
    dbref newparent;
    char rbuf[BUFFER_LEN];
    char qbuf[BUFFER_LEN];
    char buf[BUFFER_LEN];
    dbref room;
    struct match_data md;
    dbref parent;

    if (!Builder(player) && !tp_all_can_build_rooms) {
        anotify_nolisten2(player, CFAIL NOBBIT_MESG);
        return;
    }

    if (!tp_building || tp_db_readonly) {
        anotify_nolisten2(player, CFAIL NOBUILD_MESG);
        return;
    }

    if (*name == '\0') {
        anotify_nolisten2(player, CINFO "You need name for the room.");
        return;
    }

    if (!ok_name(name)) {
        anotify_nolisten2(player, CINFO "That's a silly name for a room!");
        return;
    }

    if (!payfor(player, tp_room_cost)) {
        anotify_fmt(player, CFAIL "You don't have enough %s to dig a room.",
                    tp_pennies);
        return;
    }
    room = new_object(player);

    /* Initialize everything */
    newparent = DBFETCH(DBFETCH(player)->location)->location;
    while ((OkObj(newparent)) && !(FLAGS(newparent) & ABODE)
           && !(FLAG2(newparent) & F2PARENT))
        newparent = DBFETCH(newparent)->location;
    if (!OkObj(newparent)) {
        if (OkObj(tp_default_parent))
            newparent = tp_default_parent;
        else
            newparent = GLOBAL_ENVIRONMENT;
    }

    NAME(room) = alloc_string(name);
    DBFETCH(room)->location = newparent;
    OWNER(room) = OWNER(player);
    DBFETCH(room)->exits = NOTHING;
    DBFETCH(room)->sp.room.dropto = NOTHING;
    FLAGS(room) = TYPE_ROOM | (FLAGS(player) & JUMP_OK);
    PUSH(room, DBFETCH(newparent)->contents);
    DBDIRTY(room);
    DBDIRTY(newparent);

    sprintf(buf, CSUCC "Room %s created.", unparse_object(player, room));
    anotify_nolisten2(player, buf);

    strcpy(buf, pname);
    for (rname = buf; (*rname && (*rname != '=')); rname++) ;
    qname = rname;
    if (*rname)
        *(rname++) = '\0';
    while ((qname > buf) && (isspace(*qname)))
        *(qname--) = '\0';
    qname = buf;
    for (; *rname && isspace(*rname); rname++) ;
    rname = strcpy(rbuf, rname);
    qname = strcpy(qbuf, qname);

    if (*qname) {
        anotify_nolisten2(player, CNOTE "Trying to set parent...");
        init_match(descr, player, qname, TYPE_ROOM, &md);
        match_absolute(&md);
        match_registered(&md);
        match_here(&md);
        if ((parent = noisy_match_result(&md)) == NOTHING
            || parent == AMBIGUOUS) {
            anotify_nolisten2(player, CINFO "Parent set to default.");
        } else {
            if ((!can_link_to(player, Typeof(room), parent)
                 && !(FLAG2(parent) & F2PARENT)) || room == parent) {
                anotify_nolisten2(player,
                                  CFAIL
                                  "Permission denied.  Parent set to default.");
            } else {
                moveto(room, parent);
                sprintf(buf, CSUCC "Parent set to %s.",
                        unparse_object(player, parent));
                anotify_nolisten2(player, buf);
            }
        }
    }

    if (*rname) {
        PData pdat;

        sprintf(buf, "_reg/%s", rname);
        pdat.flags = PROP_REFTYP;
        pdat.data.ref = room;
        set_property(player, buf, &pdat);
        sprintf(buf, CINFO "Room registered as $%s", rname);
        anotify_nolisten2(player, buf);
    }
}
Beispiel #11
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;
}
Beispiel #12
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;
}