/* Display the map to the player */ void show_map( CHAR_DATA * ch, char *text ) { char buf[MAX_STRING_LENGTH * 2]; int x, y, pos; char *p; bool alldesc = FALSE; /* Has desc been fully displayed? */ if ( !text ) alldesc = TRUE; pos = 0; p = text; buf[0] = '\0'; /* * Show exits */ if ( xIS_SET( ch->act, PLR_AUTOEXIT ) ) snprintf( buf, MAX_STRING_LENGTH * 2, "%s%s", color_str( AT_EXITS, ch ), get_exits( ch ) ); else mudstrlcpy( buf, "", MAX_STRING_LENGTH * 2 ); /* * Top of map frame */ mudstrlcat( buf, "&z+-----------+&w ", MAX_STRING_LENGTH * 2 ); if ( !alldesc ) { pos = get_line( p, 63 ); if ( pos > 0 ) { mudstrlcat( buf, color_str( AT_RMDESC, ch ), MAX_STRING_LENGTH * 2 ); strncat( buf, p, pos ); p += pos; } else { mudstrlcat( buf, color_str( AT_RMDESC, ch ), MAX_STRING_LENGTH * 2 ); mudstrlcat( buf, p, MAX_STRING_LENGTH * 2 ); alldesc = TRUE; } } mudstrlcat( buf, "\r\n", MAX_STRING_LENGTH * 2 ); /* * Write out the main map area with text */ for ( y = 0; y <= MAPY; ++y ) { mudstrlcat( buf, "&z|&D", MAX_STRING_LENGTH * 2 ); for ( x = 0; x <= MAPX; ++x ) { switch ( dmap[x][y].tegn ) { case '-': case '|': case '\\': case '/': snprintf( buf + strlen( buf ), ( MAX_STRING_LENGTH * 2 ) - strlen( buf ), "&O%c&d", dmap[x][y].tegn ); break; case '@': // Character is standing here snprintf( buf + strlen( buf ), ( MAX_STRING_LENGTH * 2 ) - strlen( buf ), "&R%c&d", dmap[x][y].tegn ); break; case 'O': // Indoors snprintf( buf + strlen( buf ), ( MAX_STRING_LENGTH * 2 ) - strlen( buf ), "&w%c&d", dmap[x][y].tegn ); break; case '=': snprintf( buf + strlen( buf ), ( MAX_STRING_LENGTH * 2 ) - strlen( buf ), "&B%c&d", dmap[x][y].tegn ); break; case '~': snprintf( buf + strlen( buf ), ( MAX_STRING_LENGTH * 2 ) - strlen( buf ), "&C%c&d", dmap[x][y].tegn ); break; case '+': snprintf( buf + strlen( buf ), ( MAX_STRING_LENGTH * 2 ) - strlen( buf ), "&Y%c&d", dmap[x][y].tegn ); break; case '*': snprintf( buf + strlen( buf ), ( MAX_STRING_LENGTH * 2 ) - strlen( buf ), "&g%c&d", dmap[x][y].tegn ); break; case 'X': snprintf( buf + strlen( buf ), ( MAX_STRING_LENGTH * 2 ) - strlen( buf ), "&R%c&d", dmap[x][y].tegn ); break; case ':': snprintf( buf + strlen( buf ), ( MAX_STRING_LENGTH * 2 ) - strlen( buf ), "&Y%c&d", dmap[x][y].tegn ); break; default: // Empty space snprintf( buf + strlen( buf ), ( MAX_STRING_LENGTH * 2 ) - strlen( buf ), "%c", dmap[x][y].tegn ); break; } } mudstrlcat( buf, "&z|&D ", MAX_STRING_LENGTH * 2 ); /* * Add the text, if necessary */ if ( !alldesc ) { pos = get_line( p, 63 ); char col[10], c[2]; strcpy( c, whatColor( text, p ) ); if ( c[0] == '\0' ) mudstrlcpy( col, color_str( AT_RMDESC, ch ), 10 ); else snprintf( col, 10, "%s", c ); if ( pos > 0 ) { mudstrlcat( buf, col, MAX_STRING_LENGTH * 2 ); strncat( buf, p, pos ); p += pos; } else { mudstrlcat( buf, col, MAX_STRING_LENGTH * 2 ); mudstrlcat( buf, p, MAX_STRING_LENGTH * 2 ); alldesc = TRUE; } } mudstrlcat( buf, "\r\n", MAX_STRING_LENGTH * 2 ); } /* * Finish off map area */ mudstrlcat( buf, "&z+-----------+&D ", MAX_STRING_LENGTH * 2 ); if ( !alldesc ) { char col[10], c[2]; pos = get_line( p, 63 ); strcpy( c, whatColor( text, p ) ); if ( c[0] == '\0' ) mudstrlcpy( col, color_str( AT_RMDESC, ch ), 10 ); else snprintf( col, 10, "%s", c ); if ( pos > 0 ) { mudstrlcat( buf, col, MAX_STRING_LENGTH * 2 ); strncat( buf, p, pos ); p += pos; mudstrlcat( buf, "\r\n", MAX_STRING_LENGTH * 2 ); } else { mudstrlcat( buf, col, MAX_STRING_LENGTH * 2 ); mudstrlcat( buf, p, MAX_STRING_LENGTH * 2 ); alldesc = TRUE; } } /* * Deal with any leftover text */ if ( !alldesc ) { char col[10], c[2]; do { /* * Note the number - no map to detract from width */ pos = get_line( p, 78 ); strcpy( c, whatColor( text, p ) ); if ( c[0] == '\0' ) mudstrlcpy( col, color_str( AT_RMDESC, ch ), 10 ); else snprintf( col, 10, "%s", c ); if ( pos > 0 ) { mudstrlcat( buf, col, MAX_STRING_LENGTH * 2 ); strncat( buf, p, pos ); p += pos; mudstrlcat( buf, "\r\n", MAX_STRING_LENGTH * 2 ); } else { mudstrlcat( buf, col, MAX_STRING_LENGTH * 2 ); mudstrlcat( buf, p, MAX_STRING_LENGTH * 2 ); alldesc = TRUE; } } while ( !alldesc ); } mudstrlcat( buf, "&D\r\n", MAX_STRING_LENGTH * 2 ); send_to_char( buf, ch ); }
void do_list( CHAR_DATA *ch, char *argument ) { if ( IS_SET(ch->in_room->room_flags, ROOM_PET_SHOP) ) { ROOM_INDEX_DATA *pRoomIndexNext; CHAR_DATA *pet; bool found; pRoomIndexNext = get_room_index( ch->in_room->vnum + 1 ); if ( !pRoomIndexNext ) { bug( "Do_list: bad pet shop at vnum %d.", ch->in_room->vnum ); send_to_char( "You can't do that here.\n\r", ch ); return; } found = FALSE; for ( pet = pRoomIndexNext->first_person; pet; pet = pet->next_in_room ) { if ( IS_SET(pet->act, ACT_PET) && IS_NPC(pet) ) { if ( !found ) { found = TRUE; send_to_char( "Pets for sale:\n\r", ch ); } ch_printf( ch, "[%2d] %8d - %s\n\r", pet->top_level, 10 * pet->top_level * pet->top_level, pet->short_descr ); } } if ( !found ) send_to_char( "Sorry, we're out of pets right now.\n\r", ch ); return; } else { char arg[MAX_INPUT_LENGTH]; CHAR_DATA *keeper; OBJ_DATA *obj; int cost; int oref = 0; bool found; one_argument( argument, arg ); if ( ( keeper = find_keeper( ch ) ) == NULL ) return; found = FALSE; for ( obj = keeper->last_carrying; obj; obj = obj->prev_content ) { if ( obj->wear_loc == WEAR_NONE && can_see_obj( ch, obj ) ) { oref++; if ( ( cost = get_cost( ch, keeper, obj, TRUE ) ) > 0 && ( arg[0] == '\0' || nifty_is_name( arg, obj->name ) ) ) { if (keeper->home != NULL) cost = obj->cost; if ( !found ) { found = TRUE; ch_printf( ch, "%s[Price] {ref} Item\n\r", color_str( AT_LIST, ch) ); } ch_printf( ch, "%s[%5d] {%3d} %s%s%s.\n\r", color_str(AT_LIST, ch), cost, oref, capitalize( obj->short_descr ), color_str(AT_LIST, ch), IS_SET(obj->extra_flags, ITEM_HUTT_SIZE) ? " (hutt size)" : ( IS_SET(obj->extra_flags, ITEM_LARGE_SIZE) ? " (large)" : ( IS_SET(obj->extra_flags, ITEM_HUMAN_SIZE) ? " (medium)" : ( IS_SET(obj->extra_flags, ITEM_SMALL_SIZE) ? " (small)" : "" ) ) ) ); } } } if ( !found ) { if ( arg[0] == '\0' ) send_to_char( "You can't buy anything here.\n\r", ch ); else send_to_char( "You can't buy that here.\n\r", ch ); } return; } }
/* * Quixadhal - I rewrote this from scratch. It now returns the number of * characters in the SOURCE string that should be skipped, it always fills * the DESTINATION string with a valid translation (even if that is itself, * or an empty string), and the default for ANSI is FALSE, since mobs and * logfiles shouldn't need colour. * * NOTE: dstlen is the length of your pre-allocated buffer that you passed * in. It must be at least 3 bytes, but should be long enough to hold the * longest translation sequence (probably around 16-32). * * NOTE: vislen is the "visible" length of the translation token. This is * used by color_strlen to properly figure the visual length of a string. * If you need the number of bytes (such as for output buffering), use the * normal strlen function. */ int colorcode( const char *src, char *dst, DESCRIPTOR_DATA * d, int dstlen, int *vislen ) { CHAR_DATA *ch = NULL; bool ansi = FALSE; const char *sympos = NULL; /* * No descriptor, assume ANSI conversion can't be done. */ if( !d ) ansi = FALSE; /* * But, if we have one, check for a PC and set accordingly. If no PC, assume ANSI can be done. For color logins. */ else { ch = d->original ? d->original : d->character; if( ch ) ansi = ( !IS_NPC( ch ) && xIS_SET( ch->act, PLR_ANSI ) ); else ansi = TRUE; } if( !dst ) return 0; /* HEY, I said at least 3 BYTES! */ dst[0] = '\0'; /* Initialize the the default NOTHING */ /* * Move along, nothing to see here */ if( !src || !*src ) return 0; switch ( *src ) { case '&': /* NORMAL, Foreground colour */ switch ( src[1] ) { case '&': /* Escaped self, return one of us */ dst[0] = src[0]; dst[1] = '\0'; if( vislen ) *vislen = 1; return 2; case 'Z': /* Random Ansi Foreground */ if( ansi ) mudstrlcpy( dst, random_ansi( 1 ), dstlen ); break; case '[': /* Symbolic color name */ if( ( sympos = strchr( src + 2, ']' ) ) ) { register int subcnt = 0; unsigned int sublen = 0; sublen = sympos - src - 2; for( subcnt = 0; subcnt < MAX_COLORS; subcnt++ ) { if( !strncmp( src + 2, pc_displays[subcnt], sublen ) ) { if( strlen( pc_displays[subcnt] ) == sublen ) { /* * These can only be used with a logged in char */ if( ansi && ch ) mudstrlcpy( dst, color_str( subcnt, ch ), dstlen ); if( vislen ) *vislen = 0; return sublen + 3; } } } } /* found matching ] */ /* * Unknown symbolic name, return just the sequence */ dst[0] = src[0]; dst[1] = src[1]; dst[2] = '\0'; if( vislen ) *vislen = 2; return 2; case 'i': /* Italic text */ case 'I': if( ansi ) mudstrlcpy( dst, ANSI_ITALIC, dstlen ); break; case 'v': /* Reverse colors */ case 'V': if( ansi ) mudstrlcpy( dst, ANSI_REVERSE, dstlen ); break; case 'u': /* Underline */ case 'U': if( ansi ) mudstrlcpy( dst, ANSI_UNDERLINE, dstlen ); break; case 's': /* Strikeover */ case 'S': if( ansi ) mudstrlcpy( dst, ANSI_STRIKEOUT, dstlen ); break; case 'd': /* Player's client default color */ if( ansi ) mudstrlcpy( dst, ANSI_RESET, dstlen ); break; case 'D': /* Reset to custom color for whatever is being displayed */ if( ansi ) { /* * Yes, this reset here is quite necessary to cancel out other things */ mudstrlcpy( dst, ANSI_RESET, dstlen ); if( ch && ch->desc ) mudstrlcat( dst, color_str( ch->desc->pagecolor, ch ), dstlen ); } break; case 'x': /* Black */ if( ansi ) mudstrlcpy( dst, ANSI_BLACK, dstlen ); break; case 'O': /* Orange/Brown */ if( ansi ) mudstrlcpy( dst, ANSI_ORANGE, dstlen ); break; case 'c': /* Cyan */ if( ansi ) mudstrlcpy( dst, ANSI_CYAN, dstlen ); break; case 'z': /* Dark Grey */ if( ansi ) mudstrlcpy( dst, ANSI_DGREY, dstlen ); break; case 'g': /* Dark Green */ if( ansi ) mudstrlcpy( dst, ANSI_DGREEN, dstlen ); break; case 'G': /* Light Green */ if( ansi ) mudstrlcpy( dst, ANSI_GREEN, dstlen ); break; case 'P': /* Pink/Light Purple */ if( ansi ) mudstrlcpy( dst, ANSI_PINK, dstlen ); break; case 'r': /* Dark Red */ if( ansi ) mudstrlcpy( dst, ANSI_DRED, dstlen ); break; case 'b': /* Dark Blue */ if( ansi ) mudstrlcpy( dst, ANSI_DBLUE, dstlen ); break; case 'w': /* Grey */ if( ansi ) mudstrlcpy( dst, ANSI_GREY, dstlen ); break; case 'Y': /* Yellow */ if( ansi ) mudstrlcpy( dst, ANSI_YELLOW, dstlen ); break; case 'C': /* Light Blue */ if( ansi ) mudstrlcpy( dst, ANSI_LBLUE, dstlen ); break; case 'p': /* Purple */ if( ansi ) mudstrlcpy( dst, ANSI_PURPLE, dstlen ); break; case 'R': /* Red */ if( ansi ) mudstrlcpy( dst, ANSI_RED, dstlen ); break; case 'B': /* Blue */ if( ansi ) mudstrlcpy( dst, ANSI_BLUE, dstlen ); break; case 'W': /* White */ if( ansi ) mudstrlcpy( dst, ANSI_WHITE, dstlen ); break; default: /* Unknown sequence, return all the chars */ dst[0] = src[0]; dst[1] = src[1]; dst[2] = '\0'; if( vislen ) *vislen = 2; return 2; } break; case '^': /* BACKGROUND colour */ switch ( src[1] ) { case '^': /* Escaped self, return one of us */ dst[0] = src[0]; dst[1] = '\0'; if( vislen ) *vislen = 1; return 2; case 'Z': /* Random Ansi Background */ if( ansi ) mudstrlcpy( dst, random_ansi( 3 ), dstlen ); break; case 'x': /* Black */ if( ansi ) mudstrlcpy( dst, BACK_BLACK, dstlen ); break; case 'r': /* Dark Red */ if( ansi ) mudstrlcpy( dst, BACK_DRED, dstlen ); break; case 'g': /* Dark Green */ if( ansi ) mudstrlcpy( dst, BACK_DGREEN, dstlen ); break; case 'O': /* Orange/Brown */ if( ansi ) mudstrlcpy( dst, BACK_ORANGE, dstlen ); break; case 'b': /* Dark Blue */ if( ansi ) mudstrlcpy( dst, BACK_DBLUE, dstlen ); break; case 'p': /* Purple */ if( ansi ) mudstrlcpy( dst, BACK_PURPLE, dstlen ); break; case 'c': /* Cyan */ if( ansi ) mudstrlcpy( dst, BACK_CYAN, dstlen ); break; case 'w': /* Grey */ if( ansi ) mudstrlcpy( dst, BACK_GREY, dstlen ); break; case 'z': /* Dark Grey */ if( ansi ) mudstrlcpy( dst, BACK_DGREY, dstlen ); break; case 'R': /* Red */ if( ansi ) mudstrlcpy( dst, BACK_RED, dstlen ); break; case 'G': /* Green */ if( ansi ) mudstrlcpy( dst, BACK_GREEN, dstlen ); break; case 'Y': /* Yellow */ if( ansi ) mudstrlcpy( dst, BACK_YELLOW, dstlen ); break; case 'B': /* Blue */ if( ansi ) mudstrlcpy( dst, BACK_BLUE, dstlen ); break; case 'P': /* Pink */ if( ansi ) mudstrlcpy( dst, BACK_PINK, dstlen ); break; case 'C': /* Light Blue */ if( ansi ) mudstrlcpy( dst, BACK_LBLUE, dstlen ); break; case 'W': /* White */ if( ansi ) mudstrlcpy( dst, BACK_WHITE, dstlen ); break; default: /* Unknown sequence, return all the chars */ dst[0] = src[0]; dst[1] = src[1]; dst[2] = '\0'; if( vislen ) *vislen = 2; return 2; } break; case '}': /* BLINK Foreground colour */ switch ( src[1] ) { case '}': /* Escaped self, return one of us */ dst[0] = src[0]; dst[1] = '\0'; if( vislen ) *vislen = 1; return 2; case 'Z': /* Random Ansi Blink */ if( ansi ) mudstrlcpy( dst, random_ansi( 2 ), dstlen ); break; case 'x': /* Black */ if( ansi ) mudstrlcpy( dst, BLINK_BLACK, dstlen ); break; case 'O': /* Orange/Brown */ if( ansi ) mudstrlcpy( dst, BLINK_ORANGE, dstlen ); break; case 'c': /* Cyan */ if( ansi ) mudstrlcpy( dst, BLINK_CYAN, dstlen ); break; case 'z': /* Dark Grey */ if( ansi ) mudstrlcpy( dst, BLINK_DGREY, dstlen ); break; case 'g': /* Dark Green */ if( ansi ) mudstrlcpy( dst, BLINK_DGREEN, dstlen ); break; case 'G': /* Light Green */ if( ansi ) mudstrlcpy( dst, BLINK_GREEN, dstlen ); break; case 'P': /* Pink/Light Purple */ if( ansi ) mudstrlcpy( dst, BLINK_PINK, dstlen ); break; case 'r': /* Dark Red */ if( ansi ) mudstrlcpy( dst, BLINK_DRED, dstlen ); break; case 'b': /* Dark Blue */ if( ansi ) mudstrlcpy( dst, BLINK_DBLUE, dstlen ); break; case 'w': /* Grey */ if( ansi ) mudstrlcpy( dst, BLINK_GREY, dstlen ); break; case 'Y': /* Yellow */ if( ansi ) mudstrlcpy( dst, BLINK_YELLOW, dstlen ); break; case 'C': /* Light Blue */ if( ansi ) mudstrlcpy( dst, BLINK_LBLUE, dstlen ); break; case 'p': /* Purple */ if( ansi ) mudstrlcpy( dst, BLINK_PURPLE, dstlen ); break; case 'R': /* Red */ if( ansi ) mudstrlcpy( dst, BLINK_RED, dstlen ); break; case 'B': /* Blue */ if( ansi ) mudstrlcpy( dst, BLINK_BLUE, dstlen ); break; case 'W': /* White */ if( ansi ) mudstrlcpy( dst, BLINK_WHITE, dstlen ); break; default: /* Unknown sequence, return all the chars */ dst[0] = src[0]; dst[1] = src[1]; dst[2] = '\0'; if( vislen ) *vislen = 2; return 2; } break; default: /* Just a normal character */ dst[0] = *src; dst[1] = '\0'; if( vislen ) *vislen = 1; return 1; } if( vislen ) *vislen = 0; return 2; }
static void print_entry_long(int * widths, struct tfile * file) { const char * ansi_color_str = color_str(&file->statbuf); /* file permissions */ if (S_ISLNK(file->statbuf.st_mode)) { printf("l"); } else if (S_ISCHR(file->statbuf.st_mode)) { printf("c"); } else if (S_ISBLK(file->statbuf.st_mode)) { printf("b"); } else if (S_ISDIR(file->statbuf.st_mode)) { printf("d"); } else { printf("-"); } printf( (file->statbuf.st_mode & S_IRUSR) ? "r" : "-"); printf( (file->statbuf.st_mode & S_IWUSR) ? "w" : "-"); if (file->statbuf.st_mode & S_ISUID) { printf("s"); } else { printf( (file->statbuf.st_mode & S_IXUSR) ? "x" : "-"); } printf( (file->statbuf.st_mode & S_IRGRP) ? "r" : "-"); printf( (file->statbuf.st_mode & S_IWGRP) ? "w" : "-"); printf( (file->statbuf.st_mode & S_IXGRP) ? "x" : "-"); printf( (file->statbuf.st_mode & S_IROTH) ? "r" : "-"); printf( (file->statbuf.st_mode & S_IWOTH) ? "w" : "-"); printf( (file->statbuf.st_mode & S_IXOTH) ? "x" : "-"); printf( " %*d ", widths[0], file->statbuf.st_nlink); /* number of links, not supported */ char tmp[100]; print_username(tmp, file->statbuf.st_uid); printf("%-*s ", widths[1], tmp); print_username(tmp, file->statbuf.st_gid); printf("%-*s ", widths[2], tmp); if (human_readable) { print_human_readable_size(tmp, file->statbuf.st_size); printf("%*s ", widths[3], tmp); } else { printf("%*d ", widths[3], (int)file->statbuf.st_size); } char time_buf[80]; struct tm * timeinfo = localtime((time_t*)&file->statbuf.st_mtime); if (timeinfo->tm_year == this_year) { strftime(time_buf, 80, "%b %d %H:%M", timeinfo); } else { strftime(time_buf, 80, "%b %d %Y", timeinfo); } printf("%s ", time_buf); /* Print the file name */ if (stdout_is_tty) { printf("\033[%sm%s\033[0m", ansi_color_str, file->name); if (S_ISLNK(file->statbuf.st_mode)) { const char * s = color_str(&file->statbufl); printf(" -> \033[%sm%s\033[0m", s, file->link); } } else { printf("%s", file->name); if (S_ISLNK(file->statbuf.st_mode)) { printf(" -> %s", file->link); } } printf("\n"); }
static int process(char *filename,RUBBLE_PILE *rp,BOOLEAN sim_units,double *time) { enum {next,mass,radius,density,pos,vel,orient,spin,color,agg_id,par_id}; SSIO ssio; SSHEAD h; int i,choice; assert(rp != NULL); *time = 0.0; if (ssioOpen(filename,&ssio,SSIO_READ)) { (void) fprintf(stderr,"Unable to open \"%s\"\n",filename); return 1; } if (ssioHead(&ssio,&h) || h.n_data < 0) { (void) fprintf(stderr,"Corrupt header\n"); (void) ssioClose(&ssio); return 1; } if (h.n_data == 0) { (void) fprintf(stderr,"No data found!"); (void) ssioClose(&ssio); return 1; } switch(h.iMagicNumber) { case SSIO_MAGIC_STANDARD: break; case SSIO_MAGIC_REDUCED: (void) fprintf(stderr,"Reduced ss format not supported.\n"); ssioClose(&ssio); return 1; default: (void) fprintf(stderr,"Unrecognized ss file magic number (%i).\n",h.iMagicNumber); ssioClose(&ssio); return 1; } rp->n_particles = h.n_data; *time = h.time; (void) printf("Number of particles = %i (time %g)\n",rp->n_particles,*time); rpuMalloc(rp); for (i=0;i<rp->n_particles;i++) if (ssioData(&ssio,&rp->data[i])) { (void) fprintf(stderr,"Corrupt data\n"); (void) ssioClose(&ssio); return 1; } (void) ssioClose(&ssio); while (/*CONSTCOND*/1) { rpuAnalyze(rp); (void) printf("%i. Total mass = ",mass); if (sim_units) (void) printf("%g M_sun",rp->mass); else (void) printf("%g kg",rp->mass*M_SCALE); (void) printf("\n"); (void) printf("%i. Bulk radius = ",radius); if (sim_units) (void) printf("%g AU",rp->radius); else (void) printf("%g km",rp->radius*0.001*L_SCALE); (void) printf("\n"); (void) printf(" [Bulk semi-axes: "); if (sim_units) (void) printf("%g %g %g AU", rp->axis_len[rp->axis_ord[X]], rp->axis_len[rp->axis_ord[Y]], rp->axis_len[rp->axis_ord[Z]]); else (void) printf("%g %g %g km", rp->axis_len[rp->axis_ord[X]]*0.001*L_SCALE, rp->axis_len[rp->axis_ord[Y]]*0.001*L_SCALE, rp->axis_len[rp->axis_ord[Z]]*0.001*L_SCALE); (void) printf("]\n"); (void) printf("%i. Bulk density = ",density); if (sim_units) (void) printf("%g M_sun/AU^3",rp->density); else (void) printf("%g g/cc",rp->density*0.001*D_SCALE); (void) printf("\n"); (void) printf("%i. Centre-of-mass position = ",pos); if (sim_units) (void) printf("%g %g %g AU",rp->pos[X],rp->pos[Y], rp->pos[Z]); else (void) printf("%.2f %.2f %.2f km",rp->pos[X]*0.001*L_SCALE, rp->pos[Y]*0.001*L_SCALE,rp->pos[Z]*0.001*L_SCALE); (void) printf("\n"); (void) printf("%i. Centre-of-mass velocity = ",vel); if (sim_units) (void) printf("%g %g %g x 30 km/s",rp->vel[X],rp->vel[Y], rp->vel[Z]); else (void) printf("%.2f %.2f %.2f m/s",rp->vel[X]*V_SCALE, rp->vel[Y]*V_SCALE,rp->vel[Z]*V_SCALE); (void) printf("\n"); (void) printf("%i. Orientation: a1 = %6.3f %6.3f %6.3f\n",orient, rp->axes[rp->axis_ord[X]][X], rp->axes[rp->axis_ord[X]][Y], rp->axes[rp->axis_ord[X]][Z]); (void) printf(" a2 = %6.3f %6.3f %6.3f\n", rp->axes[rp->axis_ord[Y]][X], rp->axes[rp->axis_ord[Y]][Y], rp->axes[rp->axis_ord[Y]][Z]); (void) printf(" a3 = %6.3f %6.3f %6.3f\n", rp->axes[rp->axis_ord[Z]][X], rp->axes[rp->axis_ord[Z]][Y], rp->axes[rp->axis_ord[Z]][Z]); (void) printf("%i. Spin = ",spin); if (sim_units) (void) printf("%g %g %g x 2pi rad/yr", rp->spin[X],rp->spin[Y],rp->spin[Z]); else { double scale = 3600/(TWO_PI*T_SCALE),w; (void) printf("%.2f %.2f %.2f 1/h (",rp->spin[X]*scale, rp->spin[Y]*scale,rp->spin[Z]*scale); w = MAG(rp->spin); if (w) (void) printf("period %g h",1/(w*scale)); else (void) printf("no spin"); (void) printf(")"); } (void) printf("\n"); (void) printf(" [Ang mom = "); if (sim_units) (void) printf("%g %g %g (sys units)",rp->ang_mom[X], rp->ang_mom[Y],rp->ang_mom[Z]); else { double scale = M_SCALE*SQ(L_SCALE)/T_SCALE; (void) printf("%.5e %.5e %.5e N m/s",rp->ang_mom[X]*scale, rp->ang_mom[Y]*scale,rp->ang_mom[Z]*scale); } (void) printf("]\n"); (void) printf(" [Effective spin = "); if (sim_units) (void) printf("%g x 2pi rad/yr",rp->eff_spin); else { double scale = 3600/(TWO_PI*T_SCALE); (void) printf("%.2f 1/h (",rp->eff_spin*scale); if (rp->eff_spin) printf("period %g h",1/(rp->eff_spin*scale)); else (void) printf("no spin"); (void) printf(")"); } (void) printf("]\n"); (void) printf(" [Rotation index = %.2f (",rp->rot_idx); if (rp->eff_spin == 0.0) (void) printf("undefined"); else if (rp->rot_idx == 1.0) (void) printf("unif rot about max moment"); else if (rp->rot_idx < 1.0 && rp->rot_idx > 0.0) (void) printf("SAM"); else if (rp->rot_idx == 0.0) (void) printf("unif rot about mid moment"); else if (rp->rot_idx < 0.0 && rp->rot_idx > -1.0) (void) printf("LAM"); else if (rp->rot_idx == -1.0) (void) printf("unif rot about min moment"); else assert(0); (void) printf(")]\n"); (void) printf("%i. Color = %i (%s)\n",color,(int) rp->color, color_str(rp->color)); (void) printf("%i. Aggregate ID = ",agg_id); if (rp->agg_id < 0) (void) printf("N/A"); else (void) printf("%i",(int) rp->agg_id); (void) printf("\n"); (void) printf("%i. Particle ID\n",par_id); do { (void) printf("Enter number to change (or 0 to continue): "); (void) scanf("%i",&choice); (void) getchar(); } while (choice < next || choice > par_id); if (choice == next) return 0; switch(choice) { case mass: { double f; BOOLEAN const_den = get_yn("Keep bulk density constant","n"),proceed=TRUE; do { (void) printf("Enter mass scaling factor (-ve ==> abs val): "); (void) scanf("%lf",&f); if (f == 0.0) { getchar(); proceed = get_yn("WARNING: This will set all particle masses to zero...continue","n"); } } while (!proceed); if (f < 0) { if (!sim_units) f /= M_SCALE; f = -f/rp->mass; } rpuScaleMass(rp,f); if (const_den) rpuScaleRadius(rp,pow(f,1.0/3),FALSE); break; } case radius: { double f; BOOLEAN just_particles = get_yn("Just scale particles","n"),const_den = FALSE; if (!just_particles) const_den = get_yn("Keep bulk density constant","n"); do { (void) printf("Enter radius scaling factor " "(-ve ==> abs val): "); (void) scanf("%lf",&f); } while (f == 0); getchar(); if (f < 0) { if (!sim_units) f *= 1000/L_SCALE; if (!just_particles) f = -f/rp->radius; } rpuScaleRadius(rp,f,just_particles); if (just_particles) rpuCalcRadius(rp); /* because outer edge may have changed */ if (const_den) rpuScaleMass(rp,CUBE(f)); break; } case density: { double f; BOOLEAN const_radius = get_yn("Keep radius constant","y"); do { (void) printf("Enter density scaling factor (-ve ==> abs val): "); (void) scanf("%lf",&f); } while (f == 0); getchar(); if (f < 0) { if (!sim_units) f *= 1000/D_SCALE; f = -f/rp->density; } if (const_radius) rpuScaleMass(rp,f); else rpuScaleRadius(rp,pow(f,-1.0/3),FALSE); break; } case pos: { BOOLEAN absolute = get_yn("Specify absolute position","y"); if (absolute) { SCALE_VEC(rp->pos,-1.0); rpuApplyPos(rp); /* reset COM to (0,0,0) first */ (void) printf("Enter new position [x y z in "); } else (void) printf("Enter position offset [x y z in "); if (sim_units) (void) printf("AU"); else (void) printf("km"); (void) printf("]: "); (void) scanf("%lf%lf%lf",&rp->pos[X],&rp->pos[Y],&rp->pos[Z]); (void) getchar(); if (!sim_units) NORM_VEC(rp->pos,0.001*L_SCALE); rpuApplyPos(rp); break; } case vel: { BOOLEAN absolute = get_yn("Specify absolute velocity","y"); if (absolute) { SCALE_VEC(rp->vel,-1.0); rpuApplyVel(rp); (void) printf("Enter new velocity [vx vy vz in "); } else (void) printf("Enter velocity offset [vx vy vz in "); if (sim_units) (void) printf("units of 30 km/s"); else (void) printf("m/s"); (void) printf("]: "); (void) scanf("%lf%lf%lf",&rp->vel[X],&rp->vel[Y],&rp->vel[Z]); (void) getchar(); if (!sim_units) NORM_VEC(rp->vel,V_SCALE); rpuApplyVel(rp); break; } case orient: { enum {x=1,y,z}; MATRIX rot; double angle; BOOLEAN align,body,rndm; int choice; align = get_yn("Align body axes with coordinate axes","n"); if (align) { MATRIX m; COPY_VEC(rp->axes[MAJOR(rp)],m[X]); COPY_VEC(rp->axes[INTER(rp)],m[Y]); COPY_VEC(rp->axes[MINOR(rp)],m[Z]); rpuRotate(rp,m,FALSE); break; } body = get_yn("Use body axes","n"); (void) printf("%i. Rotate about %s axis\n",x,body?"major":"x"); (void) printf("%i. Rotate about %s axis\n",y,body?"intermediate":"y"); (void) printf("%i. Rotate about %s axis\n",z,body?"minor":"z"); do { (void) printf("Enter choice: "); (void) scanf("%i",&choice); } while (choice < x || choice > z); --choice; /* to conform with X,Y,Z macros */ (void) getchar(); rndm = get_yn("Use random angle","n"); if (rndm) angle = TWO_PI*rand()/RAND_MAX; else { (void) printf("Enter rotation angle in "); if (sim_units) (void) printf("radians"); else (void) printf("degrees"); (void) printf(" (-ve=clockwise): "); (void) scanf("%lf",&angle); (void) getchar(); if (!sim_units) angle *= DEG_TO_RAD; } UNIT_MAT(rot); if (body) choice = rp->axis_ord[choice]; switch (choice) { case X: rot[Y][Y] = cos(angle); rot[Y][Z] = -sin(angle); rot[Z][Y] = -rot[Y][Z]; rot[Z][Z] = rot[Y][Y]; break; case Y: rot[X][X] = cos(angle); rot[X][Z] = sin(angle); rot[Z][X] = -rot[X][Z]; rot[Z][Z] = rot[X][X]; break; case Z: rot[X][X] = cos(angle); rot[X][Y] = -sin(angle); rot[Y][X] = -rot[X][Y]; rot[Y][Y] = rot[X][X]; break; default: assert(0); } rpuRotate(rp,rot,body); break; } case spin: { VECTOR old_spin,d; double w_max = 2*PI/sqrt(3*PI/rp->density); BOOLEAN incr_only,ang_mom,body; COPY_VEC(rp->spin,old_spin); /* needed for spin increment */ /*DEBUG following only removes net spin---it does not ensure that every particle has wxr_i = 0 and w_i = 0*/ SCALE_VEC(rp->spin,-1.0); rpuAddSpin(rp,FALSE); /* remove current spin */ (void) printf("Classical breakup limit for measured density = "); if (sim_units) (void) printf("%g x 2pi rad/yr",w_max); else (void) printf("%g 1/h (P_min = %g h)", 3600*w_max/(TWO_PI*T_SCALE), TWO_PI*T_SCALE/(3600*w_max)); (void) printf("\n"); incr_only = get_yn("Specify increment only, instead of absolute value","n"); if (incr_only) ang_mom = get_yn("Specify angular momentum increment","n"); else ang_mom = get_yn("Specify angular momentum","n"); if (ang_mom) { if (incr_only) (void) printf("Enter angular momentum increment [dlx dly dlz in "); else (void) printf("Enter new angular momentum [lx ly lz in "); if (sim_units) (void) printf("sys units"); else (void) printf("N m/s"); (void) printf("]: "); (void) scanf("%lf%lf%lf",&d[X],&d[Y],&d[Z]); (void) getchar(); if (!sim_units) SCALE_VEC(d,T_SCALE/(SQ(L_SCALE)*M_SCALE)); if (incr_only) { ADD_VEC(rp->ang_mom,d,rp->ang_mom); } else { COPY_VEC(d,rp->ang_mom); } rpuAddAngMom(rp); if (MAG(rp->spin) > w_max) (void) printf("WARNING: exceeds classical breakup limit\n"); break; } body = get_yn("Use body axes","n"); if (incr_only) (void) printf("Enter spin increment [dwx dwy dwz in "); else (void) printf("Enter new spin [wx wy wz in "); if (sim_units) (void) printf("units of 2pi rad/yr"); else (void) printf("1/h"); (void) printf("]: "); (void) scanf("%lf%lf%lf",&d[X],&d[Y],&d[Z]); (void) getchar(); if (!sim_units) SCALE_VEC(d,TWO_PI*T_SCALE/3600); if (incr_only) { ADD_VEC(old_spin,d,rp->spin); } else { COPY_VEC(d,rp->spin); } if (MAG(rp->spin) > w_max) (void) printf("WARNING: exceeds classical breakup limit\n"); rpuAddSpin(rp,body); break; } case color: { BOOLEAN invalid_color; int c; (void) printf("Color scheme:\n"); for (i=BLACK;i<FIRST_GRAY;i++) (void) printf("%2i. %s\n",i,color_str(i)); do { invalid_color = FALSE; (void) printf("Enter new color: "); (void) scanf("%i",&c); (void) getchar(); if (c >= NUM_COLORS) { /* allow negative colors */ (void) printf("Invalid color\n"); invalid_color = TRUE; continue; } if (c == BLACK || c == FIRST_GRAY) (void) printf("WARNING: Particles may be invisible!\n"); } while (invalid_color); rp->color = c; rpuApplyColor(rp); break; } case agg_id: { do { (void) printf("Enter new aggregate ID (or -1 to reset): "); (void) scanf("%i",&rp->agg_id); (void) getchar(); if (rp->agg_id < -1) (void) printf("Invalid ID\n"); else rpuApplyAggID(rp); } while(rp->agg_id < -1); break; } case par_id: { SSDATA *p,*pmax; VECTOR r; double lng,lat,dmax,d; int c; (void) printf("Enter angular coordinates [lng lat in deg]: "); (void) scanf("%lf%lf",&lng,&lat); (void) getchar(); lng *= DEG_TO_RAD; lat *= DEG_TO_RAD; SET_VEC(r,cos(lng)*cos(lat),sin(lng)*cos(lat),sin(lat)); dmax = 0.0; pmax = NULL; for (i=0;i<rp->n_particles;i++) { p = &rp->data[i]; /* projected distance along vector minus distance perpendicular to vector favors particles closest to vector */ d = DOT(p->pos,r) - sqrt(MAG_SQ(p->pos) - SQ(DOT(p->pos,r))); if (d > dmax) { dmax = d; pmax = p; } } if (!pmax) { (void) printf("No particle found.\n"); continue; } (void) printf("Found particle (original index %i, color %i [%s])\n", pmax->org_idx,pmax->color,color_str(pmax->color)); while (/*CONSTCOND*/1) { (void) printf("Enter new color: "); (void) scanf("%i",&c); (void) getchar(); if (c >= NUM_COLORS) { /* allow negative colors */ (void) printf("Invalid color\n"); goto invalid; } if (c == BLACK || c == RED || c == YELLOW || c == MAGENTA || c == CYAN || c == KHAKI || c == FIRST_GRAY) { (void) printf("Color %i is reserved\n",c); goto invalid; } break; invalid: (void) printf("Color scheme:\n"); for (i=BLACK;i<FIRST_GRAY;i++) (void) printf("%2i. %s\n",i,color_str(i)); }; /* while */ pmax->color = c; break; } default: assert(0); } } }
static void process(SSDATA *d,int n,double *t) { PROPERTIES p; int choice; enum {Next,Time,Mass,Bounds,ComPos,ComVel,AngMom,VelDsp,Color,Units, Offsets,Masses,Radii,End}; while (/*CONSTCOND*/1) { ss_analyze(d,n,&p); (void) printf("%2i. Time = %g\n",Time,*t); (void) printf("%2i. Total mass = %g\n",Mass,p.total_mass); (void) printf("%2i. Bounds: x=[%g,%g]\n" " y=[%g,%g]\n" " z=[%g,%g]\n",Bounds, p.bnd_min[X],p.bnd_max[X], p.bnd_min[Y],p.bnd_max[Y], p.bnd_min[Z],p.bnd_max[Z]); (void) printf("%2i. Centre-of-mass position = %g %g %g\n",ComPos, p.com_pos[X],p.com_pos[Y],p.com_pos[Z]); (void) printf("%2i. Centre-of-mass velocity = %g %g %g\n",ComVel, p.com_vel[X],p.com_vel[Y],p.com_vel[Z]); (void) printf("%2i. Specific angular momentum = %g %g %g\n",AngMom, p.ang_mom[X],p.ang_mom[Y],p.ang_mom[Z]); (void) printf("%2i. Velocity dispersion = %g %g %g\n",VelDsp, p.vel_dsp[X],p.vel_dsp[Y],p.vel_dsp[Z]); (void) printf("%2i. Dominant color = %i (%s)\n",Color,p.color, color_str(p.color)); (void) printf("%2i. Units\n",Units); (void) printf("%2i. Offsets\n",Offsets); (void) printf("%2i. Particle masses\n",Masses); (void) printf("%2i. Particle radii\n",Radii); do { (void) printf("Enter number to change (or 0 to continue): "); (void) scanf("%i",&choice); } while (choice < Next || choice >= End); (void) getchar(); if (choice == Next) return; switch(choice) { case Time: do { (void) printf("Enter new time: "); (void) scanf("%lf",t); (void) getchar(); } while (*t < 0); break; case Mass: { double f; do get_scaling(&f,NegativeOK); while (f == 0); if (f < 0) f = -f/p.total_mass; scale_mass(d,n,f); break; } case Bounds: { double f,min,max; int i,choice; do { do { (void) printf("%i. Change x bounds (now [%g,%g])\n",X + 1, p.bnd_min[X],p.bnd_max[X]); (void) printf("%i. Change y bounds (now [%g,%g])\n",Y + 1, p.bnd_min[Y],p.bnd_max[Y]); (void) printf("%i. Change z bounds (now [%g,%g])\n",Z + 1, p.bnd_min[Z],p.bnd_max[Z]); (void) printf("Your choice (or 0 when done): "); (void) scanf("%i",&choice); (void) getchar(); } while (choice < 0 || choice > N_DIM); if (choice == 0) break; --choice; /* put back in range [X,Z] */ if (p.bnd_min[choice] == p.bnd_max[choice]) { (void) printf("Chosen dimension is degenerate\n"); continue; } do { (void) printf("Enter new bounds (min max): "); (void) scanf("%lf%lf",&min,&max); (void) getchar(); } while (min > max); if (min == max && get_yn("Zero velocities for this component","y")) for (i=0;i<n;i++) d[i].vel[choice] = 0; f = (max - min)/(p.bnd_max[choice] - p.bnd_min[choice]); for (i=0;i<n;i++) d[i].pos[choice] = (d[i].pos[choice] - p.bnd_min[choice])*f + min; p.bnd_min[choice] = min; p.bnd_max[choice] = max; } while (/*CONSTCOND*/1); break; } case ComPos: { VECTOR v; if (MAG(p.com_pos) && get_yn("Scale the magnitude","y")) { double f; get_scaling(&f,NegativeOK); COPY_VEC(p.com_pos,v); if (f < 0) f = -f/MAG(v); SCALE_VEC(v,f); } else get_components(v); adj_com_pos(d,n,&p,v); break; } case ComVel: { VECTOR v; if (MAG(p.com_vel) && get_yn("Scale the magnitude","y")) { double f; get_scaling(&f,NegativeOK); COPY_VEC(p.com_vel,v); if (f < 0) f = -f/MAG(v); SCALE_VEC(v,f); } else get_components(v); adj_com_vel(d,n,&p,v); break; } case AngMom: { VECTOR v; (void) printf("NOTE: specific angular momentum is measured with\n" "respect to fixed space frame centred at (0,0,0)\n" "and does not take particle spins into account\n"); if (MAG(p.ang_mom) && get_yn("Scale the magnitude","y")) { double f; get_scaling(&f,NegativeOK); COPY_VEC(p.ang_mom,v); if (f < 0) f = -f/MAG(p.ang_mom); SCALE_VEC(v,f); } else if (get_yn("Scale the components","y")) { VECTOR u; int k; get_component_scaling(u); for (k=0;k<N_DIM;k++) v[k] = u[k]*p.ang_mom[k]; } else get_components(v); adj_ang_mom(d,n,&p,v); break; } case VelDsp: { VECTOR v; (void) printf("NOTE: velocity dispersion is context dependent,\n" "for now relative ONLY to center-of-mass velocity,\n" "i.e. without considering bulk rotation or shear\n"); if (!MAG(p.vel_dsp)) { (void) printf("Zero velocity dispersion -- cannot adjust\n"); break; } if (get_yn("Scale the magnitude","y")) { double f; get_scaling(&f,NegativeOK); if (f < 0) f = -f/MAG(p.vel_dsp); SET_VEC(v,f,f,f); } else get_component_scaling(v); scale_vel_dsp(d,n,&p,v); break; } case Color: { int c; (void) printf("Color scheme:\n"); for (c=BLACK;c<FIRST_GRAY;c++) (void) printf("%2i. %s\n",c,color_str(c)); (void) printf("[values from %i to %i are levels of gray]\n", FIRST_GRAY,LAST_GRAY); do { (void) printf("Enter new color: "); (void) scanf("%i",&c); (void) getchar(); } while (c < 0 || c >= NUM_COLORS); change_color(d,n,c); break; } case Units: { enum {N,M,L,T,V,E}; double f; int i,choice; (void) printf("NOTE: It is up to you to ensure dimensions are\n" "internally consistent. pkdgrav assumes G == 1.\n"); do { do { (void) printf("%i. Mass (particle masses)\n",M); (void) printf("%i. Length (particle radii, pos'ns)\n",L); (void) printf("%i. Time (time,particle spins)\n",T); (void) printf("%i. Velocity (particle velocities)\n",V); (void) printf("Select dimension to scale " "(or 0 when done): "); (void) scanf("%i",&choice); (void) getchar(); } while (choice < N || choice >= E); if (choice == N) break; switch (choice) { case M: (void) printf("M_Sun = 1.9891e30 kg\n" "M_Earth = 5.9742e24 kg\n" "M_Jupiter = 1.8992e27 kg\n" "M_Saturn = 5.6864e26 kg\n"); get_scaling(&f,PositiveOnly); for (i=0;i<n;i++) d[i].mass *= f; break; case L: (void) printf("1 AU = 1.49597892e11 m\n" "R_Earth = 6.37814e6 m\n"); get_scaling(&f,PositiveOnly); for (i=0;i<n;i++) { d[i].radius *= f; SCALE_VEC(d[i].pos,f); } break; case T: (void) printf("1 yr = 3.15576e7 s\n" "1 yr / 2 pi = 5.02255e6 s\n"); get_scaling(&f,PositiveOnly); *t *= f; for (i=0;i<n;i++) NORM_VEC(d[i].spin,f); break; case V: (void) printf("V_Earth = 2.97852586e4 m/s\n"); get_scaling(&f,PositiveOnly); for (i=0;i<n;i++) SCALE_VEC(d[i].vel,f); break; default: assert(0); } } while (/*CONSTCOND*/1); break; } case Offsets: { VECTOR v; int i; (void) printf("POSITION OFFSET (0 0 0 for none)...\n"); get_components(v); for (i=0;i<n;i++) ADD_VEC(d[i].pos,v,d[i].pos); (void) printf("VELOCITY OFFSET (0 0 0 for none)...\n"); get_components(v); for (i=0;i<n;i++) ADD_VEC(d[i].vel,v,d[i].vel); break; } case Masses: { double f; do get_scaling(&f,NegativeOK); while (f == 0); scale_masses(d,n,f); break; } case Radii: { double f; do get_scaling(&f,NegativeOK); while (f == 0); scale_radii(d,n,f); break; } default: assert(0); } } }