/** * Accesses a sector from a set of sector coords (sector_t) */ world_sector_t* world_get_sector(world_t* world, sector_t sector) { if (world->sectors[sector.x][sector.y][sector.z] == (world_sector_t*)NULL) { world->sectors[sector.x][sector.y][sector.z] = sector_create(sector); } return world->sectors[sector.x][sector.y][sector.z]; }
int addconstellation(char* cname) { unsigned long nums, numc, i; char *string; struct sector *fs, *s; struct ptrlist work; double phi; unsigned long r; string = malloc(strlen(cname)+GREEK_LEN+2); if (!string) return -1; ptrlist_init(&work); /* Determine number of sectors in constellation */ nums = mtrandom_uint(GREEK_N); if (nums == 0) nums = 1; mprintf("addconstellation: will create %lu sectors (universe has %lu so far)\n", nums, ptrlist_len(&univ.sectors)); pthread_rwlock_wrlock(&univ.sectornames_lock); fs = NULL; for (numc = 0; numc < nums; numc++) { /* Create a new sector and put it in s */ s = malloc(sizeof(*s)); if (!s) goto err; sprintf(string, "%s %s", greek[numc], cname); if (sector_create(s, string)) goto err; ptrlist_push(&univ.sectors, s); st_add_string(&univ.sectornames, s->name, s); if (fs == NULL) { /* This was the first sector generated for this constellation We need to place this at a suitable point in the universe */ fs = s; if (ptrlist_len(&univ.sectors) == 1) { /* The first constellation always goes in (0, 0) */ if (sector_move(s, 0, 0)) bug("%s", "Error when placing first sector at (0,0)"); } else { /* All others are randomly distributed */ phi = mtrandom_uint(UINT_MAX) / (double)UINT_MAX*2*M_PI; r = 0; i = 2; while (i > 1) { r += mtrandom_ulong(CONSTELLATION_RANDOM_DISTANCE); phi += mtrandom_double(CONSTELLATION_PHI_RANDOM); if (!sector_move(s, POLTOX(phi, r), POLTOY(phi, r))) i = get_neighbouring_systems(NULL, s, CONSTELLATION_MIN_DISTANCE); } } ptrlist_push(&work, s); } else if (ptrlist_len(&work) == 0) { /* This isn't the first sector but no sectors are left in work Put this close to the first sector */ ptrlist_push(&work, s); makeneighbours(fs, s, 0, 0); } else { /* We have sectors in work, put this close to work[0] and add this one to work */ ptrlist_push(&work, s); makeneighbours(ptrlist_entry(&work, 0), s, 0, 0); /* Determine if work[0] has enough neighbours, if so remove it */ if (mtrandom_uint(UINT_MAX) < UINT_MAX/CONSTELLATION_NEIGHBOUR_CHANCE) ptrlist_pull(&work); } mprintf("Created %s (%p) at %ldx%ld\n", s->name, s, s->x, s->y); } pthread_rwlock_unlock(&univ.sectornames_lock); free(string); ptrlist_free(&work); return 0; err: pthread_rwlock_unlock(&univ.sectornames_lock); return -1; }