/**************************************************************************** Initialize data structures required for edit mode. ****************************************************************************/ void edithand_init(void) { if (NULL != modified_tile_table) { tile_hash_destroy(modified_tile_table); } modified_tile_table = tile_hash_new(); need_continents_reassigned = FALSE; if (unfogged_players != NULL) { free(unfogged_players); } unfogged_players = fc_calloc(player_slot_count(), sizeof(bool)); }
/**************************************************************************** Initializes all player research structure. ****************************************************************************/ void player_researches_init(void) { int i; /* Ensure we have enough space for players or teams. */ fc_assert(ARRAY_SIZE(research_array) >= team_slot_count()); fc_assert(ARRAY_SIZE(research_array) >= player_slot_count()); memset(research_array, 0, sizeof(*research_array)); for (i = 0; i < ARRAY_SIZE(research_array); i++) { research_array[i].tech_goal = A_UNSET; research_array[i].researching = A_UNSET; research_array[i].researching_saved = A_UNKNOWN; } }
/************************************************************************** Find a player or a user by prefix. prefix - The prefix. matches - A string array to set the matches result. max_matches - The maximum of matches. match_len - The length of the string used to returns matches. Returns the number of the matches names. **************************************************************************/ static int check_player_or_user_name(const char *prefix, const char **matches, const int max_matches) { int matches_id[max_matches * 2], ind, num; switch (match_prefix_full(get_player_or_user_name, player_slot_count() + conn_list_size(game.all_connections), MAX_LEN_NAME, fc_strncasecmp, strlen, prefix, &ind, matches_id, max_matches * 2, &num)) { case M_PRE_EXACT: case M_PRE_ONLY: matches[0] = get_player_or_user_name(ind); return 1; case M_PRE_AMBIGUOUS: { /* Remove duplications playername/username. */ const char *name; int i, j, c = 0; for (i = 0; i < num && c < max_matches; i++) { name = get_player_or_user_name(matches_id[i]); for (j = 0; j < c; j++) { if (0 == fc_strncasecmp(name, matches[j], MAX_LEN_NAME)) { break; } } if (j >= c) { matches[c++] = name; } } return c; } case M_PRE_EMPTY: case M_PRE_LONG: case M_PRE_FAIL: case M_PRE_LAST: break; } return 0; }
/**************************************************************************** Called when the client first starts to allocate the default colors. Currently this must be called in ui_main, generally after UI initialization. ****************************************************************************/ struct color_system *color_system_read(struct section_file *file) { int i; struct color_system *colors = fc_malloc(sizeof(*colors)); fc_assert_ret_val(ARRAY_SIZE(color_names) == COLOR_LAST, NULL); for (i = 0; i < COLOR_LAST; i++) { if (!secfile_lookup_int(file, &colors->colors[i].r, "colors.%s0.r", color_names[i]) || !secfile_lookup_int(file, &colors->colors[i].g, "colors.%s0.g", color_names[i]) || !secfile_lookup_int(file, &colors->colors[i].b, "colors.%s0.b", color_names[i])) { log_error("Color %s: %s", color_names[i], secfile_error()); colors->colors[i].r = 0; colors->colors[i].g = 0; colors->colors[i].b = 0; } colors->colors[i].color = NULL; } for (i = 0; i < player_slot_count(); i++) { if (NULL == secfile_entry_lookup(file, "colors.player%d.r", i)) { break; } } colors->num_player_colors = MAX(i, 1); colors->player_colors = fc_malloc(colors->num_player_colors * sizeof(*colors->player_colors)); if (i == 0) { /* Use a simple fallback. */ log_error("Missing colors.player. See misc/colors.tilespec."); colors->player_colors[0].r = 128; colors->player_colors[0].g = 0; colors->player_colors[0].b = 0; colors->player_colors[0].color = NULL; } else { for (i = 0; i < colors->num_player_colors; i++) { struct rgbcolor *rgb = &colors->player_colors[i]; if (!secfile_lookup_int(file, &rgb->r, "colors.player%d.r", i) || !secfile_lookup_int(file, &rgb->g, "colors.player%d.g", i) || !secfile_lookup_int(file, &rgb->b, "colors.player%d.b", i)) { log_error("Player color %d: %s", i, secfile_error()); rgb->r = 0; rgb->g = 0; rgb->b = 0; } rgb->color = NULL; } } for (i = 0; i < ARRAY_SIZE(colors->terrain_colors); i++) { struct rgbcolor *rgb = &colors->terrain_colors[i]; rgb->r = rgb->g = rgb->b = 0; rgb->color = NULL; } colors->terrain_hash = terrain_color_hash_new(); for (i = 0; ; i++) { struct rgbcolor rgb; const char *key; if (!secfile_lookup_int(file, &rgb.r, "colors.tiles%d.r", i) || !secfile_lookup_int(file, &rgb.g, "colors.tiles%d.g", i) || !secfile_lookup_int(file, &rgb.b, "colors.tiles%d.b", i)) { break; } rgb.color = NULL; key = secfile_lookup_str(file, "colors.tiles%d.tag", i); if (NULL == key) { log_error("warning: tag for tiles %d: %s", i, secfile_error()); } else if (!terrain_color_hash_insert(colors->terrain_hash, key, &rgb)) { log_error("warning: already have a color for %s", key); } } return colors; }