/** 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; }
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; }
/** 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; }
/** 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); } } }
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; } } }
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); } }
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; }
}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
}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
}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
//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; }
/** 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); }
/** 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; }
/** 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; }
/** 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; }
/** 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; }
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."); }
/* 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); } }