예제 #1
0
/* utility for open and link */
static dbref
parse_linkable_room(dbref player, const char *room_name, NEW_PE_INFO *pe_info)
{
  dbref room;

  /* parse room */
  if (!strcasecmp(room_name, "here")) {
    room = speech_loc(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, pe_info)) {
    notify(player, T("You can't link to that."));
    return NOTHING;
  } else {
    return room;
  }
}
예제 #2
0
파일: speech.c 프로젝트: kymoon/pennmush
/** The teach command.
 * \param player the enactor.
 * \param tbuf1 the command being taught.
 * \param list is tbuf1 an action list, or a single command?
 * \param parent_queue the queue entry to run the command in
 */
void
do_teach(dbref player, const char *tbuf1, int list, MQUE *parent_queue)
{
  dbref loc;
  int flags = QUEUE_RECURSE;
  char lesson[BUFFER_LEN], *lp;

  loc = speech_loc(player);
  if (!GoodObject(loc))
    return;

  if (!Loud(player)
      && !eval_lock_with(player, loc, Speech_Lock, parent_queue->pe_info)) {
    fail_lock(player, loc, Speech_Lock, T("You may not speak here!"), NOTHING);
    return;
  }

  if (!tbuf1 || !*tbuf1) {
    notify(player, T("What command do you want to teach?"));
    return;
  }

  if (!list)
    flags |= QUEUE_NOLIST;

  lp = lesson;
  safe_format(lesson, &lp, T("%s types --> %s%s%s"), spname(player),
              ANSI_HILITE, tbuf1, ANSI_END);
  *lp = '\0';
  notify_anything(player, player, na_loc, &loc, NULL,
                  NA_INTER_HEAR | NA_PROPAGATE, lesson, NULL, loc, NULL);
  new_queue_actionlist(player, parent_queue->enactor, player, (char *) tbuf1,
                       parent_queue, PE_INFO_SHARE, flags, NULL);
}
예제 #3
0
파일: speech.c 프로젝트: kymoon/pennmush
/** The say command.
 * \param player the enactor.
 * \param message the message to say.
 * \param pe_info pe_info to eval speechmod with
 */
void
do_say(dbref player, const char *message, NEW_PE_INFO *pe_info)
{
  dbref loc;
  PE_REGS *pe_regs;
  char modmsg[BUFFER_LEN];
  char says[BUFFER_LEN];
  char *sp;
  int mod = 0;
  loc = speech_loc(player);
  if (!GoodObject(loc))
    return;

  if (!Loud(player) && !eval_lock_with(player, loc, Speech_Lock, pe_info)) {
    fail_lock(player, loc, Speech_Lock, T("You may not speak here!"), NOTHING);
    return;
  }

  if (*message == SAY_TOKEN && CHAT_STRIP_QUOTE)
    message++;

  pe_regs = pe_regs_create(PE_REGS_ARG, "do_say");
  pe_regs_setenv_nocopy(pe_regs, 0, message);
  pe_regs_setenv_nocopy(pe_regs, 1, "\"");
  modmsg[0] = '\0';

  if (call_attrib(player, "SPEECHMOD", modmsg, player, pe_info, pe_regs)
      && *modmsg != '\0')
    mod = 1;
  pe_regs_free(pe_regs);

  /* notify everybody */
  notify_format(player, T("You say, \"%s\""), (mod ? modmsg : message));
  sp = says;
  safe_format(says, &sp, T("%s says, \"%s\""), spname(player),
              (mod ? modmsg : message));
  *sp = '\0';
  notify_except(player, loc, player, says, NA_INTER_HEAR);
}
예제 #4
0
/** Open a new exit.
 * \verbatim
 * This is the top-level function for @open. It calls do_real_open()
 * to do the real work of opening both the exit forward and the exit back.
 * \endverbatim
 * \param player the enactor.
 * \param direction name of the exit forward.
 * \param links 1-based array, possibly containing name of destination, name of exit back,
 * and room to open initial exit from.
 * \param pe_info the pe_info to use for any lock checks
 */
void
do_open(dbref player, const char *direction, char **links, NEW_PE_INFO *pe_info)
{
  dbref forward;
  dbref source = NOTHING;

  if (links[3]) {
    source =
      match_result(player, links[3], TYPE_ROOM,
                   MAT_HERE | MAT_ABSOLUTE | MAT_TYPE);
    if (!GoodObject(source)) {
      notify(player, T("Open from where?"));
      return;
    }
  }

  if (links[5]) {
    if (!make_first_free_wrapper(player, links[5]))
      return;
  }
  if (links[4]) {
    if (!make_first_free_wrapper(player, links[4]))
      return;
  }

  forward = do_real_open(player, direction, links[1], source, pe_info);
  if (links[2] && *links[2] && GoodObject(forward)
      && GoodObject(Location(forward))) {
    char sourcestr[SBUF_LEN];   /* SBUF_LEN is the size used by unparse_dbref */
    if (!GoodObject(source)) {
      source = speech_loc(player);
    }
    strcpy(sourcestr, unparse_dbref(source));
    do_real_open(player, links[2], sourcestr, Location(forward), pe_info);
  }
}
예제 #5
0
/** Create an exit.
 * This function opens an exit and optionally links it.
 * \param player the enactor.
 * \param direction the name of the exit.
 * \param linkto the room to link to, as a string.
 * \param pseudo a phony location for player if a back exit is needed. This is bpass by do_open() as the source room of the back exit.
 * \param pe_info the pe_info to use for any lock checks
 * \return dbref of the new exit, or NOTHING.
 */
dbref
do_real_open(dbref player, const char *direction, const char *linkto,
             dbref pseudo, NEW_PE_INFO *pe_info)
{
  dbref loc = (pseudo != NOTHING) ? pseudo : speech_loc(player);
  dbref new_exit;
  char *flaglist, *flagname;
  char flagbuff[BUFFER_LEN];
  char *name = NULL;
  char *alias = NULL;

  if (!command_check_byname(player, "@dig", NULL)) {
    notify(player, T("Permission denied."));
    return NOTHING;
  }
  if ((loc == NOTHING) || (!IsRoom(loc))) {
    notify(player, T("Sorry, you can only make exits out of rooms."));
    return NOTHING;
  }
  if (Going(loc)) {
    notify(player, T("You can't make an exit in a place that's crumbling."));
    return NOTHING;
  }
  if (!*direction) {
    notify(player, T("Open where?"));
    return NOTHING;
  } else
    if (ok_object_name
        ((char *) direction, player, NOTHING, TYPE_EXIT, &name,
         &alias) != OPAE_SUCCESS) {
    notify(player, T("That's a strange name for an exit!"));
    if (name)
      mush_free(name, "name.newname");
    if (alias)
      mush_free(alias, "name.newname");
    return NOTHING;
  }
  if (!can_open_from(player, loc, pe_info)) {
    notify(player, T("Permission denied."));
  } else if (can_pay_fees(player, EXIT_COST)) {
    /* create the exit */
    new_exit = new_object();

    /* initialize everything */
    set_name(new_exit, name);
    Owner(new_exit) = Owner(player);
    Zone(new_exit) = Zone(player);
    Source(new_exit) = loc;
    Type(new_exit) = TYPE_EXIT;
    Flags(new_exit) = new_flag_bitmask("FLAG");
    strcpy(flagbuff, options.exit_flags);
    flaglist = trim_space_sep(flagbuff, ' ');
    if (*flaglist != '\0') {
      while (flaglist) {
        flagname = split_token(&flaglist, ' ');
        twiddle_flag_internal("FLAG", new_exit, flagname, 0);
      }
    }

    mush_free(name, "name.newname");
    if (alias) {
      if (*alias != ALIAS_DELIMITER)
        atr_add(new_exit, "ALIAS", alias, player, 0);
      mush_free(alias, "name.newname");
    }

    /* link it in */
    PUSH(new_exit, Exits(loc));

    /* and we're done */
    notify_format(player, T("Opened exit %s"), unparse_dbref(new_exit));

    /* check second arg to see if we should do a link */
    if (linkto && *linkto != '\0') {
      notify(player, T("Trying to link..."));
      if ((loc = check_var_link(linkto)) == NOTHING)
        loc = parse_linkable_room(player, linkto, pe_info);
      if (loc != NOTHING) {
        if (!payfor(player, LINK_COST)) {
          notify_format(player, T("You don't have enough %s to link."), MONIES);
        } else {
          /* it's ok, link it */
          Location(new_exit) = loc;
          notify_format(player, T("Linked exit #%d to #%d"), new_exit, loc);
        }
      }
    }
    current_state.exits++;
    local_data_create(new_exit);
    queue_event(player, "OBJECT`CREATE", "%s", unparse_objid(new_exit));
    return new_exit;
  }
  if (name)
    mush_free(name, "name.newname");
  if (alias)
    mush_free(alias, "name.newname");

  return NOTHING;
}