diff --git a/src/cup.c b/src/cup.c index 3dd5205a..c899fdd8 100644 --- a/src/cup.c +++ b/src/cup.c @@ -319,6 +319,8 @@ cup_get_team_pointers(Cup *cup, gint round, GPtrArray *teams_sorted, gboolean pr g_ptr_array_add(teams, &g_array_index(cup_round->teams, Team, i)); } + country_lookup_first_team_ids(&country); + if(debug > 70) for(i=0;ilen;i++) g_print("cup_get_team_pointers: %s round %d team %d %s (clid %d)\n", diff --git a/src/job.c b/src/job.c index d78150e3..bbf329f4 100644 --- a/src/job.c +++ b/src/job.c @@ -426,6 +426,7 @@ job_change_country(Job *job) Player, k).team = &g_array_index(lig(i).teams, Team, j); } + country_lookup_first_team_ids(&country); stat5 = -1; /* Set season to 1 so that some special things diff --git a/src/league.c b/src/league.c index 97380af2..831a7881 100644 --- a/src/league.c +++ b/src/league.c @@ -1144,3 +1144,31 @@ league_cup_get_week_with_break(gint clid, gint week_number) return week_number; } + +/** Lookup the first_team_id from the first_team_sid for each team in the + * country. This will allow faster lookups of the first team. This needs to + * be called after both xml_country_read() and team_generate_players_stadium() + * have been called, since those functions are what complete loads all the teams + * in a country. */ +void +country_lookup_first_team_ids(const Country *country) +{ + gint i,j; + for (i = 0; i < country->leagues->len; i++) { + const League *league = &g_array_index(country->leagues, League, i); + for (j = 0; j < league->teams->len; j++) { + Team *team = &g_array_index(league->teams, Team, j); + if (!team_is_reserve_team(team)) { + team->first_team_id = team->id; + continue; + } + + /* Check if we have already computed the first_team ID */ + if (team->first_team_id != 0) + continue; + + const Team *first_team = team_of_sid(team->first_team_sid, country); + team->first_team_id = first_team->id; + } + } +} diff --git a/src/league.h b/src/league.h index 87678e87..7829f469 100644 --- a/src/league.h +++ b/src/league.h @@ -170,4 +170,7 @@ league_cup_adjust_week_breaks(GArray *week_breaks, gint week_gap); gint league_cup_get_week_with_break(gint clid, gint week_number); +void +country_lookup_first_team_ids(const Country *country); + #endif diff --git a/src/start_end.c b/src/start_end.c index bee720e2..ccb8bf87 100644 --- a/src/start_end.c +++ b/src/start_end.c @@ -251,6 +251,7 @@ start_generate_league_teams(void) for(j=0;jlen;j++) team_generate_players_stadium(&g_array_index(lig(i).teams, Team, j), 0); + country_lookup_first_team_ids(&country); stat5 = -1; } diff --git a/src/team.c b/src/team.c index 35480b47..83e6a7b5 100644 --- a/src/team.c +++ b/src/team.c @@ -69,6 +69,9 @@ team_new(gboolean new_id) new.luck = 1; new.players = g_array_new(FALSE, FALSE, sizeof(Player)); + new.first_team_sid = NULL; + new.first_team_id = 0; + new.reserve_level = 0; return new; } @@ -252,6 +255,38 @@ team_of_id(gint id) return NULL; } +/** Return the pointer to the team belonging to the sid. */ +Team * +team_of_sid(const char *sid, const Country *country) +{ + gint i, j, k; + for (i = 0; i < country->leagues->len; i++) { + const League *league = &g_array_index(country->leagues, League, i); + for (j = 0; j < league->teams->len; j++ ) { + Team *team = &g_array_index(league->teams, Team, j); + if (!strcmp(team->name, sid)) + return team; + } + } + + for( i = 0; i < country->cups->len; i++) { + const Cup *cup = &g_array_index(country->cups, Cup, i); + for (j = 0; j < cup->rounds->len; j++) { + const CupRound *round = &g_array_index(cup->rounds, CupRound, j); + for (k = 0; k < round->teams->len; k++) { + Team * team = &g_array_index(round->teams, Team, k); + if (!strcmp(team->name, sid)) + return team; + } + } + } + + main_exit_program(EXIT_POINTER_NOT_FOUND, + "team_of_sid: team with sid %s not found.", sid); + + return NULL; +} + /** Return a pointer to the next or last fixture the team participates in. @param tm The team we examine. @return The pointer to the fixture or NULL if none is found. */ @@ -1428,3 +1463,9 @@ team_write_overall_results(const Team *tm, gint clid, gchar *results) sprintf(results, "%d-%d-%d, %d:%d", won, lost, drawn, gf, ga); } + +gboolean +team_is_reserve_team(const Team *tm) +{ + return tm->first_team_sid != NULL; +} diff --git a/src/team.h b/src/team.h index daf9b184..00b5f9f9 100644 --- a/src/team.h +++ b/src/team.h @@ -64,6 +64,9 @@ team_get_pointers_from_array(const GArray *teams, GPtrArray *team_ptrs); Team* team_of_id(gint id); +Team* +team_of_sid(const char *sid, const Country *country); + const Fixture* team_get_fixture(const Team *tm, gboolean last_fixture); @@ -160,4 +163,7 @@ team_complete_def_sort(Team *tm); gint team_get_table_clid(const Team *tm); +gboolean +team_is_reserve_team(const Team *tm); + #endif diff --git a/src/team_struct.h b/src/team_struct.h index e8c9823b..9dd2f693 100644 --- a/src/team_struct.h +++ b/src/team_struct.h @@ -100,6 +100,23 @@ typedef struct Array of players. */ GArray *players; + + /** If this is a reserve team, then this will be the name of the the team's + * first team. Otherwise, this will be NULL. It is preferred to use + * first_team_id to access the first team. However, we need to keep a + * reference to the first team sid, because we do know the team ids yet + * for all teams when we parse team information in xml_league_read(). + * The first_team_id will be computed later once all teams have been fully + * loaded from xml. */ + gchar *first_team_sid; + /** id of the first team if this is a reserve team otherwise 0. */ + gint first_team_id; + /** The level of an reserve team. e.g. If you have teams: Green, + * Green II, and Green III. Then the reserve_level will be 0, 2, and 3 + * respectively. A value of 1 for this field is not valid. The reason + * to have Green II be level 2 and not 1 is because it makes the xml + * definitions less confusing.*/ + gint reserve_level; } Team; #endif diff --git a/src/xml_league.c b/src/xml_league.c index 08273e41..4ffeecff 100644 --- a/src/xml_league.c +++ b/src/xml_league.c @@ -67,6 +67,8 @@ #define TAG_TEAM_SYMBOL "team_symbol" #define TAG_TEAM_NAMES_FILE "team_names_file" #define TAG_TEAM_AVERAGE_TALENT "team_average_talent" +#define TAG_TEAM_FIRST_TEAM "first_team" +#define TAG_TEAM_RESERVE_LEVEL "reserve_level" #define TAG_TEAM_DEF_FILE "def_file" #define TAG_TWO_MATCH_WEEK_START "two_match_week_start" #define TAG_TWO_MATCH_WEEK_END "two_match_week_end" @@ -112,6 +114,8 @@ enum XmlLeagueStates STATE_TEAM_SYMBOL, STATE_TEAM_NAMES_FILE, STATE_TEAM_AVERAGE_TALENT, + STATE_TEAM_FIRST_TEAM, + STATE_TEAM_RESERVE_LEVEL, STATE_TEAM_DEF_FILE, STATE_BREAK, STATE_JOINED_LEAGUE, @@ -278,6 +282,10 @@ xml_league_read_start_element (GMarkupParseContext *context, state = STATE_TEAM_AVERAGE_TALENT; else if(strcmp(element_name, TAG_TEAM_DEF_FILE) == 0) state = STATE_TEAM_DEF_FILE; + else if(strcmp(element_name, TAG_TEAM_FIRST_TEAM) == 0) + state = STATE_TEAM_FIRST_TEAM; + else if(strcmp(element_name, TAG_TEAM_RESERVE_LEVEL) == 0) + state = STATE_TEAM_RESERVE_LEVEL; else debug_print_message("xml_league_read_start_element: unknown tag: %s; I'm in state %d\n", element_name, state); @@ -340,6 +348,8 @@ xml_league_read_end_element (GMarkupParseContext *context, state = STATE_TEAMS; else if(strcmp(element_name, TAG_TEAM_NAME) == 0 || strcmp(element_name, TAG_TEAM_DEF_FILE) == 0 || + strcmp(element_name, TAG_TEAM_FIRST_TEAM) == 0 || + strcmp(element_name, TAG_TEAM_RESERVE_LEVEL) == 0 || strcmp(element_name, TAG_TEAM_AVERAGE_TALENT) == 0 || strcmp(element_name, TAG_TEAM_SYMBOL) == 0 || strcmp(element_name, TAG_TEAM_NAMES_FILE) == 0) @@ -477,6 +487,10 @@ xml_league_read_text (GMarkupParseContext *context, (float_value / 10000) * const_float_fast(float_player_max_skill); else if(state == STATE_TEAM_DEF_FILE) misc_string_assign(&g_array_index(new_league.teams, Team, new_league.teams->len - 1).def_file, buf); + else if(state == STATE_TEAM_FIRST_TEAM) + misc_string_assign(&g_array_index(new_league.teams, Team, new_league.teams->len - 1).first_team_sid, buf); + else if(state == STATE_TEAM_RESERVE_LEVEL) + g_array_index(new_league.teams, Team, new_league.teams->len - 1).reserve_level = int_value; } /** diff --git a/src/xml_loadsave_teams.c b/src/xml_loadsave_teams.c index 42c80ab2..3ac6378e 100644 --- a/src/xml_loadsave_teams.c +++ b/src/xml_loadsave_teams.c @@ -50,6 +50,9 @@ enum TAG_TEAM_STADIUM_SAFETY, TAG_TEAM_LUCK, TAG_TEAM_STADIUM_TICKET_PRICE, + TAG_TEAM_FIRST_TEAM_SID, + TAG_TEAM_FIRST_TEAM_ID, + TAG_TEAM_RESERVE_LEVEL, TAG_END }; @@ -131,6 +134,9 @@ xml_loadsave_teams_end_element (GMarkupParseContext *context, tag == TAG_TEAM_STYLE || tag == TAG_TEAM_BOOST || tag == TAG_TEAM_STADIUM || + tag == TAG_TEAM_FIRST_TEAM_SID || + tag == TAG_TEAM_FIRST_TEAM_ID || + tag == TAG_TEAM_RESERVE_LEVEL || tag == TAG_TEAM_LUCK) state = TAG_TEAM; else if(tag == TAG_TEAM_STADIUM_NAME || @@ -207,6 +213,12 @@ xml_loadsave_teams_text (GMarkupParseContext *context, new_team.stadium.ticket_price = float_value; else if(state == TAG_TEAM_LUCK) new_team.luck = float_value; + else if(state == TAG_TEAM_FIRST_TEAM_SID) + misc_string_assign(&new_team.first_team_sid, buf); + else if(state == TAG_TEAM_FIRST_TEAM_ID) + new_team.first_team_id = int_value; + else if(state == TAG_TEAM_RESERVE_LEVEL) + new_team.reserve_level = int_value; else if(state >= TAG_START_PLAYERS && state <= TAG_END_PLAYERS) xml_loadsave_players_text(buf); } @@ -290,12 +302,15 @@ xml_loadsave_teams_write_team(FILE *fil, const Team* team) xml_write_string(fil, team->symbol, TAG_SYMBOL, I1); xml_write_string(fil, team->names_file, TAG_TEAM_NAMES_FILE, I1); xml_write_string(fil, team->strategy_sid, TAG_TEAM_STRATEGY_SID, I1); + xml_write_string(fil, team->first_team_sid, TAG_TEAM_FIRST_TEAM_SID, I1); xml_write_int(fil, team->clid, TAG_TEAM_CLID, I1); xml_write_int(fil, team->id, TAG_TEAM_ID, I1); xml_write_int(fil, team->structure, TAG_TEAM_STRUCTURE, I1); xml_write_int(fil, team->style, TAG_TEAM_STYLE, I1); xml_write_int(fil, team->boost, TAG_TEAM_BOOST, I1); + xml_write_int(fil, team->first_team_id, TAG_TEAM_FIRST_TEAM_ID, I1); + xml_write_int(fil, team->reserve_level, TAG_TEAM_RESERVE_LEVEL, I1); fprintf(fil, "%s<_%d>\n", I1, TAG_TEAM_STADIUM); diff --git a/src/xml_team.c b/src/xml_team.c index c10e6574..8c2d2ebf 100644 --- a/src/xml_team.c +++ b/src/xml_team.c @@ -43,6 +43,8 @@ #define TAG_AVERAGE_TALENT "average_talent" #define TAG_FORMATION "formation" #define TAG_NAMES_FILE "names_file" +#define TAG_FIRST_TEAM "first_team" +#define TAG_RESERVE_LEVEL "reserve_level" #define TAG_PLAYER "player" #define TAG_PLAYER_NAME "player_name" #define TAG_PLAYER_BIRTH_YEAR "birth_year" @@ -60,6 +62,8 @@ enum XmlTeamStates STATE_AVERAGE_TALENT, STATE_FORMATION, STATE_NAMES_FILE, + STATE_FIRST_TEAM, + STATE_RESERVE_LEVEL, STATE_PLAYER, STATE_PLAYER_NAME, STATE_PLAYER_BIRTH_YEAR, @@ -101,6 +105,10 @@ xml_team_read_start_element (GMarkupParseContext *context, state = STATE_FORMATION; else if(strcmp(element_name, TAG_NAMES_FILE) == 0) state = STATE_NAMES_FILE; + else if(strcmp(element_name, TAG_FIRST_TEAM) == 0) + state = STATE_FIRST_TEAM; + else if(strcmp(element_name, TAG_RESERVE_LEVEL) == 0) + state = STATE_RESERVE_LEVEL; else if(strcmp(element_name, TAG_PLAYER) == 0) { state = STATE_PLAYER; @@ -145,6 +153,8 @@ xml_team_read_end_element (GMarkupParseContext *context, strcmp(element_name, TAG_AVERAGE_TALENT) == 0 || strcmp(element_name, TAG_FORMATION) == 0 || strcmp(element_name, TAG_NAMES_FILE) == 0 || + strcmp(element_name, TAG_FIRST_TEAM) == 0 || + strcmp(element_name, TAG_RESERVE_LEVEL) == 0 || strcmp(element_name, TAG_PLAYER) == 0) { state = STATE_TEAM; @@ -216,6 +226,10 @@ xml_team_read_text (GMarkupParseContext *context, team->structure = int_value; else if(state == STATE_NAMES_FILE) misc_string_assign(&team->names_file, buf); + else if(state == STATE_FIRST_TEAM) + misc_string_assign(&team->first_team_sid, buf); + else if(state == STATE_RESERVE_LEVEL) + team->reserve_level = int_value; else if(state == STATE_PLAYER_NAME) misc_string_assign(&new_player.name, buf); else if(state == STATE_PLAYER_BIRTH_YEAR && opt_int("int_opt_load_defs") == 1)