static void message(struct engine *engine, const TCOD_color_t col, const char *text, ...) { TCOD_list_t log = engine->gui->log; /* Build the text */ va_list ap; char buf[128]; va_start(ap, text); vsprintf(buf, text, ap); va_end(ap); char *line_begin = buf; char *line_end; do { /* make room for the new message */ if (TCOD_list_size(log) == MSG_HEIGHT) { struct message *to_remove = TCOD_list_get(log, 0); TCOD_list_remove(log, to_remove); free(to_remove); } // detect end of the line line_end = strchr(line_begin, '\n'); if (line_end) *line_end = '\0'; // add a new message to the log struct message *msg; mkmessage(&msg, line_begin, col); TCOD_list_push(log, msg); /* go to next line */ line_begin = line_end + 1; } while (line_end); }
void TCOD_dijkstra_get(TCOD_dijkstra_t p, int index, int *x, int *y) { dijkstra_t * data = (dijkstra_t*)p; unsigned int node ; TCOD_IFNOT(data != NULL) return; node = (unsigned int)(uintptr)TCOD_list_get(data->path,TCOD_list_size(data->path)-index-1); if ( x ) *x = (int)(node % data->width); if ( y ) *y = (int)(node / data->width); }
Object sensor_visobjs_member(TCOD_list_t l, Object o) { for(int i = 0; i < TCOD_list_size(l); i++) { Object o2 = TCOD_list_get(l, i); if(strcmp(object_id(o), object_id(o2)) == 0) { return o2; } } return NULL; }
Prop structrecord_get_prop_named(StructRecord sr, char *name) { for(int i = 0; i < TCOD_list_size(sr->props); i++) { Prop p = TCOD_list_get(sr->props, i); if(strcmp(prop_name(p), name) == 0) { return p; } } return NULL; }
bool structrecord_is_flag_set(StructRecord sr, char *name) { for(int i = 0; i < TCOD_list_size(sr->flags); i++) { char *flag = TCOD_list_get(sr->flags, i); if(strcmp(flag, name) == 0) { return true; } } return false; }
void sensor_sense(Sensor s) { Map m = s->map; mapVec pos=s->borig, sz=s->bsz; memset(s->vistiles, 0, sz.x*sz.y*sz.z*sizeof(perception)); map_get_visible_tiles(m, s->vistiles, s->volume, pos, sz); Stimulus vistiles = stimulus_init_tile_vis_change(stimulus_new(), s->vistiles, pos, sz); // TCOD_console_print_left(NULL, 0, 20, "p {%f, %f, %f}, s {%f, %f, %f}", pos.x, pos.y, pos.z, sz.x, sz.y, sz.z); TCOD_list_push(s->stimuli, vistiles); TCOD_list_t oldObjList = s->visObjects; //one ago s->visObjects = s->oldVisObjects; //two ago TCOD_list_clear(s->visObjects); s->oldVisObjects = oldObjList; map_get_visible_objects(m, s->visObjects, s->vistiles, pos, sz); //remove the old objects Object o; mapVec pt; int index; Stimulus visobj; for(int i = 0; i < TCOD_list_size(s->oldVisObjects); i++) { o = TCOD_list_get(s->oldVisObjects, i); if(!TCOD_list_contains(s->visObjects, o)) { //not visible anymore //this isn't quite right, really, using percept_none here visobj = stimulus_init_obj_vis_change(stimulus_new(), o, percept_none, object_context(o)); TCOD_list_push(s->stimuli, visobj); } } //add the new objects for(int i = 0; i < TCOD_list_size(s->visObjects); i++) { o = TCOD_list_get(s->visObjects, i); if(!TCOD_list_contains(s->oldVisObjects, o)) { //not visible before pt = object_position(o); index = tile_index(pt.x, pt.y, pt.z, map_size(m), pos, sz); visobj = stimulus_init_obj_vis_change(stimulus_new(), o, s->vistiles[index], object_context(o)); TCOD_list_push(s->stimuli, visobj); } } }
void TCOD_path_get(TCOD_path_t p, int index, int *x, int *y) { int pos; TCOD_path_data_t *path=(TCOD_path_data_t *)p; TCOD_IFNOT(p != NULL) return; if ( x ) *x=path->ox; if ( y ) *y=path->oy; pos = TCOD_list_size(path->path)-1; do { int step=(int)(uintptr)TCOD_list_get(path->path,pos); if ( x ) *x += dirx[step]; if ( y ) *y += diry[step]; pos--;index--; } while (index >= 0); }
void TCOD_path_reverse(TCOD_path_t p) { int tmp,i; TCOD_path_data_t *path=(TCOD_path_data_t *)p; TCOD_IFNOT(p != NULL) return ; tmp=path->ox; path->ox=path->dx; path->dx=tmp; tmp=path->oy; path->oy=path->dy; path->dy=tmp; for (i=0; i < TCOD_list_size(path->path); i++) { int d=(int)(uintptr)TCOD_list_get(path->path,i); d = invdir[d]; TCOD_list_set(path->path,(void *)(uintptr)d,i); } }
bool TCOD_bsp_traverse_level_order(TCOD_bsp_t *node, TCOD_bsp_callback_t listener, void *userData) { TCOD_list_t stack=TCOD_list_new(); TCOD_list_push(stack,node); while ( ! TCOD_list_is_empty(stack) ) { TCOD_bsp_t *node=(TCOD_bsp_t *)TCOD_list_get(stack,0); TCOD_list_remove(stack,node); if ( TCOD_bsp_left(node) ) TCOD_list_push(stack,TCOD_bsp_left(node)); if ( TCOD_bsp_right(node) ) TCOD_list_push(stack,TCOD_bsp_right(node)); if (!listener(node,userData)) { TCOD_list_delete(stack); return false; } } TCOD_list_delete(stack); return true; }
void drawstimuli(Map m, Sensor s) { TCOD_list_t stims = sensor_consume_stimuli(s); unsigned char *tiles; mapVec pos, size, oldPt, delta; unsigned char visflags; if(TCOD_list_size(stims) > 0) { TCOD_console_print_left(NULL, 0, 10, TCOD_BKGND_NONE, " "); } for(int i = 0; i < TCOD_list_size(stims); i++) { //this is a very naive approach that completely ignores the possibility of overdraw and 'forgets' object positions Stimulus st = TCOD_list_get(stims, i); stimtype type = stimulus_type(st); TCOD_console_print_left(NULL, i*2, 10, TCOD_BKGND_NONE, "s%i", type); switch(type) { case StimTileLitChange: case StimTileVisChange: //redraw all tiles tiles = stimulus_tile_sight_change_get_new_tiles(st); pos = stimulus_tile_sight_change_get_position(st); size = stimulus_tile_sight_change_get_size(st); drawtiles(m, tiles, s, pos, size); break; case StimObjLitChange: case StimObjVisChange: //redraw object draw_object(st); break; case StimObjMoved: visflags = stimulus_obj_sight_change_get_new_flags(st); pos = stimulus_obj_sight_change_get_position(st); delta = stimulus_obj_moved_get_dir(st); oldPt = mapvec_subtract(pos, delta); TCOD_console_print_left(NULL, oldPt.x*2, oldPt.y, TCOD_BKGND_NONE, "x"); draw_object(st); TCOD_console_print_left(NULL, 0, 15, TCOD_BKGND_NONE, "got move"); break; case StimGeneric: default: TCOD_console_print_left(NULL, i*9, 16, TCOD_BKGND_NONE, "generic %d", i); break; } stimulus_free(st); } TCOD_list_delete(stims); }
/* generate a name with one of the rules from the file */ char * TCOD_namegen_generate (char * name, bool allocate) { namegen_t * data; int rule_number; int chance; char * rule_rolled; int truncation; char * rule_parsed ; char * ret ; if (namegen_generator_check(name)) data = namegen_generator_get(name); else { fprintf(stderr,"The name \"%s\" has not been found.\n",name); namegen_get_sets_on_error(); return NULL; } /* check if the rules list is present */ if (TCOD_list_size(data->rules) == 0) { fprintf(stderr,"The rules list is empty!\n"); exit(1); } /* choose the rule */ do { rule_number = TCOD_random_get_int(data->random,0,TCOD_list_size(data->rules)-1); rule_rolled = (char*)TCOD_list_get(data->rules,rule_number); chance = 100; truncation = 0; if (rule_rolled[0] == '%') { truncation = 1; chance = 0; while (rule_rolled[truncation] >= '0' && rule_rolled[truncation] <= '9') { chance *= 10; chance += (int)(rule_rolled[truncation]) - (int)('0'); truncation++; } } } while (TCOD_random_get_int(data->random,0,100) > chance); /* OK, we've got ourselves a new rule! */ rule_parsed = TCOD_strdup(rule_rolled+truncation); ret = TCOD_namegen_generate_custom(name,rule_parsed,allocate); free(rule_parsed); return ret; }
/* generate a name using a given generation rule */ char * TCOD_namegen_generate_custom (char * name, char * rule, bool allocate) { namegen_t * data; size_t buflen = 1024; char * buf ; size_t rule_len ; if (namegen_generator_check(name)) data = namegen_generator_get(name); else { fprintf(stderr,"The name \"%s\" has not been found.\n",name); namegen_get_sets_on_error(); return NULL; } buf = malloc(buflen); rule_len = strlen(rule); /* let the show begin! */ do { char * it = rule; memset(buf,'\0',buflen); while (it <= rule + rule_len) { /* make sure the buffer is large enough */ if (strlen(buf) >= buflen) { char * tmp ; while (strlen(buf) >= buflen) buflen *= 2; tmp = malloc(buflen); strcpy(tmp,buf); free(buf); buf = tmp; } /* append a normal character */ if ((*it >= 'a' && *it <= 'z') || (*it >= 'A' && *it <= 'Z') || *it == '\'' || *it == '-') strncat(buf,it,1); /* special character */ else if (*it == '/') { it++; strncat(buf,it,1); } /* underscore is converted to space */ else if (*it == '_') strcat(buf," "); /* interpret a wildcard */ else if (*it == '$') { int chance = 100; it++; /* food for the randomiser */ if (*it >= '0' && *it <= '9') { chance = 0; while (*it >= '0' && *it <= '9') { chance *= 10; chance += (int)(*it) - (int)('0'); it++; } } /* ok, so the chance of wildcard occurrence is calculated, now evaluate it */ if (chance >= TCOD_random_get_int(data->random,0,100)) { TCOD_list_t lst; switch (*it) { case 'P': lst = data->syllables_pre; break; case 's': lst = data->syllables_start; break; case 'm': lst = data->syllables_middle; break; case 'e': lst = data->syllables_end; break; case 'p': lst = data->syllables_post; break; case 'v': lst = data->vocals; break; case 'c': lst = data->consonants; break; case '?': lst = (TCOD_random_get_int(data->random,0,1) == 0 ? data->vocals : data->consonants); break; default: fprintf(stderr,"Wrong rules syntax encountered!\n"); exit(1); break; } if (TCOD_list_size(lst) == 0) fprintf(stderr,"No data found in the requested string (wildcard *%c). Check your name generation rule %s.\n",*it,rule); else strcat(buf,(char*)TCOD_list_get(lst,TCOD_random_get_int(data->random,0,TCOD_list_size(lst)-1))); } } it++; } } while (!namegen_word_is_ok(data,buf)); /* prune the spare spaces out */ namegen_word_prune_spaces(buf); /* return the name accordingly */ if (allocate == true) return buf; else { /* take care of ensuring the recipient is sized properly */ if (namegen_name == NULL) { namegen_name_size = 64; namegen_name = malloc (namegen_name_size); } while (strlen(buf) > namegen_name_size - 1) { namegen_name_size *= 2; free(namegen_name); namegen_name = malloc(namegen_name_size); } strcpy(namegen_name,buf); free(buf); return namegen_name; } }
void TCOD_map_compute_fov_diamond_raycasting(TCOD_map_t map, int player_x, int player_y, int max_radius, bool light_walls) { map_t *m = (map_t *)map; TCOD_list_t perim=TCOD_list_allocate(m->nbcells); cell_t *c; ray_data_t **r; int nbcells; int r2=max_radius*max_radius; perimidx=0; raymap=(ray_data_t **)calloc(sizeof(ray_data_t*),m->nbcells); raymap2=(ray_data_t *)calloc(sizeof(ray_data_t),m->nbcells); origx=player_x; origy=player_y; expandPerimeterFrom(m,perim,new_ray(m,0,0)); while ( perimidx < TCOD_list_size(perim) ) { ray_data_t *ray=(ray_data_t *)TCOD_list_get(perim,perimidx); int distance = 0; if ( r2 > 0 ) distance = ((ray->xloc * ray->xloc) + (ray->yloc * ray->yloc)); perimidx++; if ( distance <= r2) { merge_input(m, ray); if ( !ray->ignore ) expandPerimeterFrom(m,perim,ray); } else ray->ignore=true; } // set fov data c=m->cells; r=raymap; nbcells=m->nbcells; while ( nbcells!= 0 ) { if ( *r == NULL || (*r)->ignore || ((*r)->xerr > 0 && (*r)->xerr <= (*r)->xob ) || ((*r)->yerr > 0 && (*r)->yerr <= (*r)->yob ) ) { c->fov=0; } else { c->fov=1; } c++; r++; nbcells--; } m->cells[origx+origy*m->width].fov=1; // light walls if ( light_walls ) { int xmin=0, ymin=0, xmax=m->width, ymax=m->height; if ( max_radius > 0 ) { xmin=MAX(0,player_x-max_radius); ymin=MAX(0,player_y-max_radius); xmax=MIN(m->width,player_x+max_radius+1); ymax=MIN(m->height,player_y+max_radius+1); } TCOD_map_postproc(m,xmin,ymin,player_x,player_y,-1,-1); TCOD_map_postproc(m,player_x,ymin,xmax-1,player_y,1,-1); TCOD_map_postproc(m,xmin,player_y,player_x,ymax-1,-1,1); TCOD_map_postproc(m,player_x,player_y,xmax-1,ymax-1,1,1); } free(raymap); free(raymap2); TCOD_list_delete(perim); }