Пример #1
0
/** Given a list of warnings, return the bitmask that represents it.
 * \param player dbref to report errors to, or NOTHING.
 * \param warnings the string of warning names
 * \return a warning bitmask
 */
warn_type
parse_warnings(dbref player, const char *warnings)
{
    int found = 0;
    warn_type flags, negate_flags;
    char tbuf1[BUFFER_LEN];
    char *w, *s;
    tcheck *c;

    flags = W_NONE;
    negate_flags = W_NONE;
    if (warnings && *warnings) {
        strcpy(tbuf1, warnings);
        /* Loop through whatever's listed and add on those warnings */
        s = trim_space_sep(tbuf1, ' ');
        w = split_token(&s, ' ');
        while (w && *w) {
            found = 0;
            if (*w == '!') {
                /* Found a negated warning */
                w++;
                for (c = checklist; c->name; c++) {
                    if (!strcasecmp(w, c->name)) {
                        negate_flags |= c->flag;
                        found++;
                    }
                }
            } else {
                for (c = checklist; c->name; c++) {
                    if (!strcasecmp(w, c->name)) {
                        flags |= c->flag;
                        found++;
                    }
                }
            }
            /* At this point, we haven't matched any warnings. */
            if (!found && player != NOTHING) {
                notify_format(player, T("Unknown warning: %s"), w);
            }
            w = split_token(&s, ' ');
        }
        /* If we haven't matched anything, don't change the player's stuff */
        if (!found)
            return -1;
        return flags & ~negate_flags;
    } else
        return 0;
}
Пример #2
0
static dbref
make_player(const char *name, const char *password, const char *host,
            const char *ip)
{
  dbref player;
  char temp[SBUF_LEN];
  char *flaglist, *flagname;
  char flagbuff[BUFFER_LEN];

  player = new_object();

  /* initialize everything */
  set_name(player, name);
  Location(player) = PLAYER_START;
  Home(player) = PLAYER_START;
  Owner(player) = player;
  Parent(player) = NOTHING;
  Type(player) = TYPE_PLAYER;
  Flags(player) = new_flag_bitmask("FLAG");
  strcpy(flagbuff, options.player_flags);
  flaglist = trim_space_sep(flagbuff, ' ');
  if (*flaglist != '\0') {
    while (flaglist) {
      flagname = split_token(&flaglist, ' ');
      twiddle_flag_internal("FLAG", player, flagname, 0);
    }
  }
  if (Suspect_Site(host, player) || Suspect_Site(ip, player))
    set_flag_internal(player, "SUSPECT");
  set_initial_warnings(player);
  /* Modtime tracks login failures */
  ModTime(player) = (time_t) 0;
  (void) atr_add(player, pword_attr, password_hash(password, NULL), GOD, 0);
  giveto(player, START_BONUS); /* starting bonus */
  (void) atr_add(player, "LAST", show_time(mudtime, 0), GOD, 0);
  (void) atr_add(player, "LASTSITE", host, GOD, 0);
  (void) atr_add(player, "LASTIP", ip, GOD, 0);
  (void) atr_add(player, "LASTFAILED", " ", GOD, 0);
  snprintf(temp, sizeof temp, "%d", START_QUOTA);
  (void) atr_add(player, "RQUOTA", temp, GOD, 0);
  (void) atr_add(player, "MAILCURF", "0", GOD,
                 AF_LOCKED | AF_NOPROG | AF_WIZARD);
  add_folder_name(player, 0, "inbox");
  /* link him to PLAYER_START */
  PUSH(player, Contents(PLAYER_START));

  add_player(player);
  add_lock(GOD, player, Basic_Lock, parse_boolexp(player, "=me", Basic_Lock),
           LF_DEFAULT);
  add_lock(GOD, player, Enter_Lock, parse_boolexp(player, "=me", Basic_Lock),
           LF_DEFAULT);
  add_lock(GOD, player, Use_Lock, parse_boolexp(player, "=me", Basic_Lock),
           LF_DEFAULT);

  current_state.players++;

  local_data_create(player);

  return player;
}
Пример #3
0
/** Is a alias a valid player alias-list for thing?
 * It must be a semicolon-separated list of valid player names
 * with no more than than MAX_ALIASES names, if the player isn't
 * a wizard.
 * \param alias list to check.
 * \param player player for permission checks.
 * \param thing player who is being aliased.
 * \return One of the OPAE_* constants defined in hdrs/attrib.h
 */
enum opa_error
ok_player_alias(const char *alias, dbref player, dbref thing)
{
  char tbuf1[BUFFER_LEN], *s, *sp;
  int cnt = 0;

  if (!alias || !*alias)
    return OPAE_NULL;

  strncpy(tbuf1, alias, BUFFER_LEN - 1);
  tbuf1[BUFFER_LEN - 1] = '\0';
  s = trim_space_sep(tbuf1, ALIAS_DELIMITER);
  while (s) {
    sp = split_token(&s, ALIAS_DELIMITER);
    while (sp && *sp && *sp == ' ')
      sp++;
    if (!sp || !*sp)
      return OPAE_NULL;         /* No null aliases */
    if (!ok_player_name(sp, player, thing))
      return OPAE_INVALID;
    cnt++;
  }
  if (Wizard(player))
    return OPAE_SUCCESS;
  if (cnt > MAX_ALIASES)
    return OPAE_TOOMANY;
  return OPAE_SUCCESS;
}
Пример #4
0
/** Add a player's alias list to the player list htab.
 * \param player dbref of player to add.
 * \param alias list of names ot use as hash table keys for player,
 * semicolon-separated.
 */
void
add_player_alias(dbref player, const char *alias)
{
  char tbuf1[BUFFER_LEN], *s, *sp;
  if (!hft_initialized)
    init_hft();
  if (!alias) {
    add_player(player);
    return;
  }
  mush_strncpy(tbuf1, alias, BUFFER_LEN);
  s = trim_space_sep(tbuf1, ALIAS_DELIMITER);
  while (s) {
    sp = split_token(&s, ALIAS_DELIMITER);
    while (sp && *sp && *sp == ' ')
      sp++;
    if (sp && *sp) {
      dbref *p;
      p = slab_malloc(player_dbref_slab, NULL);
      if (!p)
        mush_panic("Unable to allocate memory in plyrlist!");
      *p = player;
      hashadd(strupper(sp), p, &htab_player_list);
    }
  }
}
Пример #5
0
void DistanceFieldFont::ParseInfo(const StringRange &line)
{
	std::stringstream ss(line.ToString());
	std::string token;

	while (ss >> token != 0) {
		std::pair<std::string, std::string> pair;
		split_token(token, pair);
		if (pair.first == "size") {
			m_fontSize = get_value<float>(pair.second);
			return;
		}
	}
}
Пример #6
0
void DistanceFieldFont::ParseCommon(const StringRange &line)
{
	std::stringstream ss(line.ToString());
	std::string token;

	while (ss >> token != 0) {
		std::pair<std::string, std::string> pair;
		split_token(token, pair);
		if (pair.first == "scaleW")
			m_sheetSize.x = get_value<float>(pair.second);
		else if (pair.first == "scaleH")
			m_sheetSize.y = get_value<float>(pair.second);
	}
}
Пример #7
0
char *skip_sort_ignore(char *s)
{
	char tok[200], *p;
	int len;
	p = CFG.sort_ignore;
	while (p) {
		p = split_token(tok, p, ',', sizeof(tok));
		len = strlen(tok);
		if (len && strncasecmp(s, tok, strlen(tok)) == 0) {
			if (s[len] == ' ' || s[len] == '\'') {
				s += len + 1;
			}
		}
	}
	return s;
}
Пример #8
0
}END_TEST

START_TEST(test_split_one_nofront){
	TokenList token;
	TokenList *tok=&token;
	int split;
	tok->token.word=strdup(">one");
	tok->token.type=TOK_OPERATOR;
	tok->next=NULL;
	split=split_token(tok,0,1);
	fail_unless(split==(SPLIT_AFTER));
	fail_unless(strcmp(tok->token.word,">")==0);
	fail_unless(strcmp(tok->next->token.word,"one")==0);
	fail_unless(tok->token.type==TOK_OPERATOR && tok->next->token.type==TOK_NULL);
	free(tok->token.word);
}END_TEST
Пример #9
0
}END_TEST

START_TEST(test_split_one_noback){
	TokenList token;
	TokenList *tok=&token;
	int split;
	tok->token.word=strdup("cmd>");
	tok->token.type=TOK_OPERATOR;
	tok->next=NULL;
	split=split_token(tok,3,4);
	fail_unless(split==(SPLIT_BEFORE));
	fail_unless(strcmp(tok->token.word,"cmd")==0);
	fail_unless(strcmp(tok->next->token.word,">")==0);
	fail_unless(tok->token.type==TOK_NULL && tok->next->token.type==TOK_OPERATOR);
	free(tok->token.word);
}END_TEST
Пример #10
0
}END_TEST

START_TEST(test_split_two){
	TokenList token;
	TokenList *tok=&token;
	int split;
	tok->token.word=strdup("cmd>>one");
	tok->token.type=TOK_OPERATOR;
	tok->next=NULL;
	split=split_token(tok,3,5);
	fail_unless(split==(SPLIT_BEFORE|SPLIT_AFTER));
	fail_unless(strcmp(tok->token.word,"cmd")==0);
	fail_unless(strcmp(tok->next->token.word,">>")==0);
	fail_unless(strcmp(tok->next->next->token.word,"one")==0);
	fail_unless(tok->token.type==TOK_NULL && tok->next->token.type==TOK_OPERATOR && tok->next->next->token.type==TOK_NULL);
	free(tok->token.word);
}END_TEST
Пример #11
0
//get font definitions from a line of xml, insert glyph information into the map
void DistanceFieldFont::ParseChar(const StringRange &r)
{
	std::stringstream ss(r.ToString());
	std::string token;

	Uint32 id = 0;
	double x = 0.0;
	double y = 0.0;
	double uSize = 0.0;
	double vSize = 0.0;
	double xoffset = 0.0;
	double yoffset = 0.0;
	double advance = 0.0;

	while (ss >> token) {
			std::pair<std::string, std::string> pair;
			split_token(token, pair);

			//only care about some values
			if (pair.first == "id")
				id = get_value<Uint32>(pair.second);
			else if (pair.first == "x")
				x = get_value<double>(pair.second);
			else if (pair.first == "y")
				y = get_value<double>(pair.second);
			else if (pair.first == "width")
				uSize = get_value<double>(pair.second);
			else if (pair.first == "height")
				vSize = get_value<double>(pair.second);
			else if (pair.first == "xoffset")
				xoffset = get_value<float>(pair.second);
			else if (pair.first == "yoffset")
				yoffset = get_value<float>(pair.second);
			else if (pair.first == "xadvance")
				advance = get_value<float>(pair.second);
	}

	const float scale = 1.f/m_fontSize;
	Glyph g;
	g.uv = vector2f(float(x)/m_sheetSize.x, float(y)/m_sheetSize.y);
	g.uvSize = vector2f(float(uSize)/m_sheetSize.x, float(vSize)/m_sheetSize.y);
	g.size = vector2f(float(uSize), float(vSize)) * scale;
	g.offset = vector2f(float(xoffset), float(m_lineHeight-vSize-yoffset)) * scale;
	g.xAdvance = advance * scale;
	m_glyphs[id] = g;
}
Пример #12
0
/** Remove a player from the player list htab.
 * \param player dbref of player to remove.
 * \param alias key to remove if given.
 */
void
delete_player(dbref player, const char *alias)
{
  if (!hft_initialized) {
    init_hft();
    return;
  }
  if (alias) {
    /* This could be a compound alias, in which case we need to delete
     * them all, but we shouldn't delete the player's own name!
     */
    char tbuf1[BUFFER_LEN], *s, *sp;
    mush_strncpy(tbuf1, alias, BUFFER_LEN);
    s = trim_space_sep(tbuf1, ALIAS_DELIMITER);
    while (s) {
      sp = split_token(&s, ALIAS_DELIMITER);
      while (sp && *sp && *sp == ' ')
        sp++;
      if (sp && *sp && strcasecmp(sp, Name(player)))
        hashdelete(strupper(sp), &htab_player_list);
    }
  } else
    hashdelete(strupper(Name(player)), &htab_player_list);
}
Пример #13
0
/** Parse access options into fields.
 * \param opts access options to read from.
 * \param who pointer to player to whom rule applies, or AMBIGUOUS.
 * \param can pointer to flags of allowed actions.
 * \param cant pointer to flags of disallowed actions.
 * \param player enactor.
 * \return number of options successfully parsed.
 * Parse options and return the appropriate can and cant bits.
 * Return the number of options successfully parsed.
 * This makes a copy of the options string, so it's not modified.
 */
int
parse_access_options(const char *opts, dbref *who, uint32_t *can,
                     uint32_t *cant, dbref player)
{
  char myopts[BUFFER_LEN];
  char *p;
  char *w;
  acsflag *c;
  int found, totalfound, first;

  if (!opts || !*opts)
    return 0;
  strcpy(myopts, opts);
  totalfound = 0;
  first = 1;
  if (who)
    *who = AMBIGUOUS;
  p = trim_space_sep(myopts, ' ');
  while ((w = split_token(&p, ' '))) {
    found = 0;

    if (first && who) {         /* Check for a character */
      first = 0;
      if (is_strict_integer(w)) {       /* We have a dbref */
        *who = parse_integer(w);
        if (*who != AMBIGUOUS && !GoodObject(*who))
          *who = AMBIGUOUS;
        continue;
      }
    }

    if (*w == '!') {
      /* Found a negated warning */
      w++;
      for (c = acslist; c->name; c++) {
        if (c->toggle && !strncasecmp(w, c->name, strlen(c->name))) {
          *cant |= c->flag;
          found++;
        }
      }
    } else {
      /* None is special */
      if (!strncasecmp(w, "NONE", 4)) {
        *cant = ACS_DEFAULT;
        found++;
      } else {
        for (c = acslist; c->name; c++) {
          if (!strncasecmp(w, c->name, strlen(c->name))) {
            *can |= c->flag;
            found++;
          }
        }
      }
    }
    /* At this point, we haven't matched any warnings. */
    if (!found) {
      if (GoodObject(player))
        notify_format(player, T("Unknown access option: %s"), w);
      else
        do_log(LT_ERR, GOD, GOD, "Unknown access flag: %s", w);
    } else {
      totalfound += found;
    }
  }
  return totalfound;
}
Пример #14
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.
 * \return dbref of the new exit, or NOTHING.
 */
dbref
do_real_open(dbref player, const char *direction, const char *linkto,
             dbref pseudo)
{
  dbref loc =
    (pseudo !=
     NOTHING) ? pseudo : (IsExit(player) ? Source(player) : (IsRoom(player) ?
                                                             player :
                                                             Location(player)));
  dbref new_exit;
  char *flaglist, *flagname;
  char flagbuff[BUFFER_LEN];
  char *name = NULL;
  char *alias = NULL;

  if (!command_check_byname(player, "@dig")) {
    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) < 1) {
    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 (!Open_Anywhere(player) && !controls(player, loc)) {
    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);
    if (alias && *alias != ALIAS_DELIMITER)
      atr_add(new_exit, "ALIAS", alias, player, 0);
    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)
      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);
      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;
}
Пример #15
0
/** Create a thing.
 * \verbatim
 * This is the top-level function for @create.
 * \endverbatim
 * \param player the enactor.
 * \param name name of thing to create.
 * \param cost pennies spent in creation.
 * \paran newdbref the (unparsed) dbref to give the object, or NULL to use the next free
 * \return dbref of new thing, or NOTHING.
 */
dbref
do_create(dbref player, char *name, int cost, char *newdbref)
{
  dbref loc;
  dbref thing;
  char *flaglist, *flagname;
  char flagbuff[BUFFER_LEN];

  if (*name == '\0') {
    notify(player, T("Create what?"));
    return NOTHING;
  } else if (!ok_name(name, 0)) {
    notify(player, T("That's a silly name for a thing!"));
    return NOTHING;
  } else if (cost < OBJECT_COST) {
    cost = OBJECT_COST;
  }

  if (!make_first_free_wrapper(player, newdbref)) {
    return NOTHING;
  }

  if (can_pay_fees(player, cost)) {
    /* create the object */
    thing = new_object();

    /* initialize everything */
    set_name(thing, name);
    if (!IsExit(player))        /* Exits shouldn't have contents! */
      Location(thing) = player;
    else
      Location(thing) = Source(player);
    Owner(thing) = Owner(player);
    Zone(thing) = Zone(player);
    s_Pennies(thing, cost);
    Type(thing) = TYPE_THING;
    Flags(thing) = new_flag_bitmask("FLAG");
    strcpy(flagbuff, options.thing_flags);
    flaglist = trim_space_sep(flagbuff, ' ');
    if (*flaglist != '\0') {
      while (flaglist) {
        flagname = split_token(&flaglist, ' ');
        twiddle_flag_internal("FLAG", thing, flagname, 0);
      }
    }


    /* home is here (if we can link to it) or player's home */
    if ((loc = Location(player)) != NOTHING &&
        (controls(player, loc) || Abode(loc))) {
      Home(thing) = loc;        /* home */
    } else {
      Home(thing) = Home(player);       /* home */
    }

    /* link it in */
    if (!IsExit(player))
      PUSH(thing, Contents(player));
    else
      PUSH(thing, Contents(Source(player)));

    /* and we're done */
    notify_format(player, T("Created: Object %s."), unparse_dbref(thing));
    current_state.things++;
    local_data_create(thing);

    queue_event(player, "OBJECT`CREATE", "%s", unparse_objid(thing));

    return thing;
  }
  return NOTHING;
}
Пример #16
0
/** Create a room.
 * \verbatim
 * This is the top-level interface for @dig.
 * \endverbatim
 * \param player the enactor.
 * \param name the name of the room to create.
 * \param argv array of additional arguments to command
 *             (exit forward,exit back,newdbref)
 * \param tport if 1, teleport the player to the new room.
 * \return dbref of new room, or NOTHING.
 */
dbref
do_dig(dbref player, const char *name, char **argv, int tport)
{
  dbref room;
  char *flaglist, *flagname;
  char flagbuff[BUFFER_LEN];
  char *newdbref = NULL;

  if (argv[3] && *argv[3]) {
    newdbref = argv[3];
  }

  /* we don't need to know player's location!  hooray! */
  if (*name == '\0') {
    notify(player, T("Dig what?"));
  } else if (!ok_name(name, 0)) {
    notify(player, T("That's a silly name for a room!"));
  } else if (can_pay_fees(player, ROOM_COST)) {
    if (!make_first_free_wrapper(player, newdbref)) {
      return NOTHING;
    }

    room = new_object();

    /* Initialize everything */
    set_name(room, name);
    Owner(room) = Owner(player);
    Zone(room) = Zone(player);
    Type(room) = TYPE_ROOM;
    Flags(room) = new_flag_bitmask("FLAG");
    strcpy(flagbuff, options.room_flags);
    flaglist = trim_space_sep(flagbuff, ' ');
    if (*flaglist != '\0') {
      while (flaglist) {
        flagname = split_token(&flaglist, ' ');
        twiddle_flag_internal("FLAG", room, flagname, 0);
      }
    }

    notify_format(player, T("%s created with room number %d."), name, room);
    if (argv[1] && *argv[1]) {
      char nbuff[MAX_COMMAND_LEN];
      sprintf(nbuff, "#%d", room);
      do_real_open(player, argv[1], nbuff, NOTHING);
    }
    if (argv[2] && *argv[2]) {
      do_real_open(player, argv[2], "here", room);
    }
    current_state.rooms++;
    local_data_create(room);
    if (tport) {
      /* We need to use the full command, because we need NO_TEL
       * and Z_TEL checking */
      char roomstr[MAX_COMMAND_LEN];
      sprintf(roomstr, "#%d", room);
      do_teleport(player, "me", roomstr, 0, 0); /* if flag, move the player */
    }
    queue_event(player, "OBJECT`CREATE", "%s", unparse_objid(room));
    return room;
  }
  return NOTHING;
}
Пример #17
0
void hs_move(dbref executor, char *arg_left, char *arg_right)
{
  huniverse *uid;
  hcelestial *cel;
  hship *dship;
  hship *ship;
  int i, dx, dy, dz;
  dbref obj;
  dbref udb, ndb;
  char *r, *s;
  int len;
  dbref bot, top;

  obj = match_result(executor, arg_left, TYPE_THING, MAT_EVERYTHING);
  if (!IsShip(obj) && !IsCelestial(obj) && !IsConsole(obj))
  {
    notify(executor, "HSPACE: Unable to move that object.");
    return;
  }
  
  s = arg_right;
  r = split_token(&s, '/');
  if (!r || !*r)
  {
    notify(executor, "HSPACE: No destination specified.");
    return;
  }
  
  len = strlen(r);
  
  ndb = match_result(executor, r, TYPE_THING, MAT_EVERYTHING);
  
  if (!RealGoodObject(ndb))
  {
    ndb = parse_dbref(r);
  }
  
  if (!RealGoodObject(ndb))
  {
    bot = 0;
    top = db_top;
  } else {
    bot = ndb;
    top = bot + 1;
  }
  
  uid = NULL;
  /* cycle through the db and try to match a space object */
  for (udb = bot; udb < top; udb++)
  {
    if (strncasecmp(Name(udb), r, len) && udb != ndb)
      continue;
    
    if (IsUniverse(udb))
    {
      uid = find_universe(udb);
    }
    else if (IsCelestial(udb))
    {
      cel = find_celestial(udb);
      if (cel)
      {
        uid = cel->uid;
        dx = cel->x;
        dy = cel->y;
        dz = cel->z;
      }
    }
    else if (IsShip(udb) || IsShipObj(udb))
    {
      dship = find_ship(udb);
      if (dship)
      {
        dx = dship->x;
        dy = dship->y;
        dz = dship->z;
        uid = dship->uid;
      }
    }
    else
    {
      /* false positive */
      continue;
    }
  
    break;
  }
  
  if (!uid)
  {
    notify(executor, "HSPACE: Unable to locate destination.");
    return;
  }
  
  if (s)
  {
    r = split_token(&s, ' ');
    if (r)
    {
      dx = parse_integer(r);
    
      r = split_token(&s, ' ');
      if (!r || !*r)
      {
        dy = 0;
        dz = 0;
      } else {
        dy = parse_integer(r);
    
        r = split_token(&s, ' ');
        if (!r || !*r)
          dz = 0;
        else
          dz = parse_integer(r);
      }
    } else {
      /* all blanks */
      dx = 0;
      dy = 0;
      dz = 0;
    }
  }
  
  if (IsShip(obj) || IsConsole(obj))
  {
    ship = find_ship(obj);
    move_ship(ship, uid, dx, dy, dz);
  }
  else if (IsCelestial(obj))
  {
    cel = find_celestial(obj);
    move_celestial(cel, uid, dx, dy, dz);
  }
  
  notify(executor, "HSPACE: Moved.");
}
Пример #18
0
/* send a standard radio communication */
void send_com(dbref from, char *arg_left, char *arg_right)
{
  dbref com, obj;
  hship *ship;
  hcelestial *cel;
  huniverse *uid;
  
  double xmit, rcv;
  char contact[32];
  char *r, *s;
  char buff[128];
  ATTR *a;
  double sx, sy, sz, tx, ty, tz, dist;
  char pre[128];
  char *mesg;
  int sent_to_from, send_to_com;
  
  if (!IsComm(from))
  {
    notify(from, "You do not have the HS_COMM flag.");
    return;
  }
  
  uid = NULL;
  obj = atr_parse_dbref(from, "HSPACE");
  if (!RealGoodObject(obj))
  {
    notify(from, "You do not have a valid space id. Board, disembark, eject, or man a console.");
    return;
  }
  
  if (IsShip(obj))
  {
    ship = find_ship_by_nav(obj);
    if (!ship)
    {
      notify(from, "Your space id is not a valid ship.");
      return;
    }
    
    if (ship->uid)
    {
      sx = ship->x;
      sy = ship->y;
      sz = ship->z;
      uid = ship->uid;
    }
    else if (ship->landed)
    {
      sx = ship->landed->x;
      sy = ship->landed->y;
      sz = ship->landed->z;
      uid = ship->landed->uid;
    }
    else if (ship->docked)
    {
      sx = ship->docked->x;
      sy = ship->docked->y;
      sz = ship->docked->z;
      uid = ship->docked->uid;
    }
    
    strncpy(contact, ship_name(ship), 10);
  }
  else if (IsCelestial(obj))
  {
    cel = find_celestial(obj);
    if (!cel)
    {
      notify(from, "Your space id is not a valid celestial.");
      return;
    }
    
    sx = cel->x;
    sy = cel->y;
    sz = cel->z;
    uid = cel->uid;

    strncpy(contact, celestial_name(cel), 10);
  }
  contact[10] = '\0';
  
  if (!uid)
  {
    notify(from, "Your space id does not have a valid uid.");
    return;
  }
  
  if (arg_left && arg_right && *arg_right)
  {
    xmit = strtod(arg_left, &s);
    
    if (s && *s)
    {
      return;
    }
    mesg = arg_right;
  } else {
    xmit = atr_parse_double(from, "TRANSMIT", 0.0);
    mesg = arg_left;
  }
  if (xmit < 100.0 || xmit > 999.9)
  {
    notify(from, "Transmission frequency must be between 100 and 999 MHz.");
    return;
  }
  
  a = atr_get(from, "CALLSIGN");
  if (!a)
  {
    snprintf(pre, 127,
         "%s%s[%s%5.1f MHz%s%s]-[%s%-10s%s]-[%s ",
         ANSI_HILITE, ANSI_BLUE, ANSI_NORMAL, xmit, ANSI_HILITE, ANSI_BLUE, ANSI_GREEN, contact,
         ANSI_BLUE, ANSI_NORMAL);
  }
  else
  {
    snprintf(pre, 127,
         "%s%s[%s%5.1f MHz%s%s]-[%s%-10s%s]-[%s %s<%s%s%s>%s ",
         ANSI_HILITE, ANSI_BLUE, ANSI_NORMAL, xmit, ANSI_HILITE, ANSI_BLUE, ANSI_GREEN, contact,
         ANSI_BLUE, ANSI_NORMAL, ANSI_CYAN, ANSI_NORMAL, atr_value(a), ANSI_CYAN, ANSI_NORMAL);
  }

  /* go through the comm list and check each one */
  sent_to_from = 0;
  for (com = 0; com < db_top; com++)
  {
    if (!IsComm(com))
      continue;
    
    /* check if the user is in the same uid */
    obj = atr_parse_dbref(com, "HSPACE");
    if (IsShip(obj))
    {
      ship = find_ship_by_nav(obj);
      if (!ship)
        continue;
      
      if (ship->uid && ship->uid != uid)
        continue;
      else if (ship->landed && ship->landed->uid != uid)
        continue;
      else if (ship->docked && ship->docked->uid != uid)
        continue;
      
      if (ship->uid)
      {
        tx = ship->x;
        ty = ship->y;
        tz = ship->z;
      }
      else if (ship->landed)
      {
        tx = ship->landed->x;
        ty = ship->landed->y;
        tz = ship->landed->z;
      }
      else if (ship->docked)
      {
        tx = ship->docked->x;
        ty = ship->docked->y;
        tz = ship->docked->z;
      }
    }
    else if (IsCelestial(obj))
    {
      cel = find_celestial(obj);
      if (!cel)
        continue;
      
      if (cel->uid != uid)
        continue;
      
      tx = cel->x;
      ty = cel->y;
      tz = cel->z;
    } else {
      continue;
    }
    
    dist = dist3d(sx, sy, sz, tx, ty, tz) / hs_options.max_comm_dist;
    if (dist > 1.0)
      continue;

    a = atr_get(com, "FREQUENCY");
    if (!a)
      continue;
    
    /* check all frequencies to see if we need to send to this com */
    send_to_com = 0;
    snprintf(buff, 127, atr_value(a));
    s = buff;
    while (s)
    {
      r = split_token(&s, ' ');
      rcv = parse_number(r);
      
      /* check to see if we're on the right frequency */
      if (fabs(rcv - xmit) < 0.1)
      {
        send_to_com = 1;
        break;
      }
    }
    
    if (send_to_com)
    {
      if (com == from)
        sent_to_from = 1;
      
      notify_format(com, "%s%s%s%s]%s", pre, decay_msg(mesg, dist), ANSI_HILITE, ANSI_BLUE, ANSI_NORMAL);
    }
  }
  
  if (!sent_to_from)
  {
    notify_format(from, "You send \"%s\" on frequency %5.1f.", mesg, xmit);
  }
}