/* job.c Bygfoot Football Manager -- a small and simple GTK2-based football management game. http://bygfoot.sourceforge.net Copyright (C) 2005 Gyözö Both (gyboth@bygfoot.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "bet.h" #include "cup.h" #include "file.h" #include "free.h" #include "job.h" #include "league.h" #include "live_game.h" #include "main.h" #include "maths.h" #include "option.h" #include "start_end.h" #include "team.h" #include "transfer.h" #include "user.h" #include "variables.h" #include "xml_country.h" /** Update the job exchange: remove expired offers and add new ones. */ void job_update(Bygfoot *bygfoot) { #ifdef DEBUG printf("job_update\n"); #endif gint i; gint new_offers, int_offers; gint national_teams = 0; for(i=jobs->len - 1; i >= 0; i--) { g_array_index(jobs, Job, i).time--; if(g_array_index(jobs, Job, i).time <= 0) job_remove(&g_array_index(jobs, Job, i), TRUE); } if(week % const_int("int_job_update_interval") != 2) return; for (i = 0; i < country.leagues->len; i++) { national_teams += g_array_index(country.leagues, League, i).teams->len; } /* Limit the total number of jobs to the number of national teams. * Otherwise, we risk hitting an infinite loop in * job_pick_team_from_country(); */ new_offers = math_rndi(const_int("int_job_new_offers_lower"), const_int("int_job_new_offers_upper")); new_offers = MIN(new_offers, national_teams - jobs->len); int_offers = (users->len == 1) ? (gint)rint((gfloat)new_offers * const_float("float_job_international_perc")) : 0; for(i=0;ilen - 1); while(g_strrstr(((Country*)g_ptr_array_index(country_list, rndom))->sid, country.sid)); job_country = g_ptr_array_index(country_list, rndom); job_pick_team_from_country(job_country, &tm, &league); new_job.country_file = g_strdup_printf("country_%s.xml", job_country->sid); new_job.time = math_rndi(const_int("int_job_update_interval") - 1, const_int("int_job_update_interval") + 1); new_job.country_name = g_strdup(job_country->name); new_job.country_rating = job_country->rating; new_job.league_name = g_strdup(league->name); new_job.league_layer = league->layer; team_id = job_team_is_in_cup(tm->name); if(team_id == -1) { new_job.team_id = tm->id; new_job.type = JOB_TYPE_INTERNATIONAL; } else { new_job.team_id = team_id; new_job.type = JOB_TYPE_CUP; } new_job.talent_percent = (gint)rint((team_get_average_talent(tm) / league->average_talent) * 100); g_array_append_val(jobs, new_job); } } /** Find out whether the country file is already loaded and part of the country array. @param len The length of the array. */ gint job_country_is_in_list(const gchar *country_file, const Country *countries, gint len) { #ifdef DEBUG printf("job_country_is_in_list\n"); #endif gint i; for(i=0;iname; new_job.league_layer = league->layer; new_job.talent_percent = (gint)rint((team_get_average_talent(tm) / league->average_talent) * 100); new_job.team_id = tm->id; g_array_append_val(jobs, new_job); } void job_pick_team_from_country(const Country *cntry, Team **tm, League **league) { #ifdef DEBUG printf("job_pick_team_from_country\n"); #endif gint i, rndom; gint team_lens[cntry->leagues->len]; team_lens[0] = g_array_index(cntry->leagues, League, 0).teams->len; for(i=1;ileagues->len;i++) team_lens[i] = team_lens[i - 1] + g_array_index(cntry->leagues, League, i).teams->len; do { rndom = math_rndi(0, team_lens[cntry->leagues->len - 1] - 1); for(i=0;ileagues->len;i++) if(rndom < team_lens[i]) { *tm = (i > 0) ? &g_array_index(g_array_index( cntry->leagues, League, i).teams, Team, rndom - team_lens[i - 1]) : &g_array_index(g_array_index( cntry->leagues, League, i).teams, Team, rndom); *league = &g_array_index(cntry->leagues, League, i); break; } } while(team_is_user(*tm) != -1 || job_team_is_on_list((*tm)->id) != -1); } /** Find out whether the team with given id is already on the job exchange list. @return The index in the jobs array if the team is on the list or -1. */ gint job_team_is_on_list(gint team_id) { #ifdef DEBUG printf("job_team_is_on_list\n"); #endif gint i; for(i=0;ilen;i++) if(g_array_index(jobs, Job, i).team_id == team_id) return i; return -1; } /** Find out whether the team with given name is participating in an international cup (and thus doesn't have to be generated). @return The id of the team if found or -1. */ gint job_team_is_in_cup(const gchar *team_name) { #ifdef DEBUG printf("job_team_is_in_cup\n"); #endif gint i, j; for(i=0;ilen;i++) for(j=0;jteams->len;j++) if(strcmp(team_name, ((Team*)g_ptr_array_index(acp(i)->teams, j))->name) == 0) return ((Team*)g_ptr_array_index(acp(i)->teams, j))->id; return -1; } /** Find the team going with the job offer. */ Team* job_get_team(const Job *job) { #ifdef DEBUG printf("job_get_team\n"); #endif gint i, j; if(job->type == JOB_TYPE_NATIONAL || job->type == JOB_TYPE_INTERNATIONAL) { return team_of_id(job->team_id); } else { for(i=0;ilen;i++) for(j=0;jteams->len;j++) if(((Team*)g_ptr_array_index(acp(i)->teams, j))->id == job->team_id) return (Team*)g_ptr_array_index(acp(i)->teams, j); } main_exit_program(EXIT_POINTER_NOT_FOUND, "job_get_team: team not found (league %s, country %s.", job->league_name, job->country_name); return NULL; } /** Find out whether the user's application for the job gets accepted. */ gboolean query_job_application_successful(const Job *job, const User *user) { #ifdef DEBUG printf("query_job_application_successful\n"); #endif gfloat success_needed; const Team *tm = job_get_team(job); gfloat user_av_skill = team_get_average_skill(user->tm, FALSE), job_av_skill = team_get_average_skill(tm, FALSE); success_needed = (job_av_skill - user_av_skill) * (gfloat)const_int("int_job_application_points_per_av_skill"); success_needed += ((gfloat)(job->league_layer - league_from_clid(user->tm->clid)->layer) * (gfloat)const_int("int_job_application_points_per_layer")); if(job->type != JOB_TYPE_NATIONAL) { success_needed += (gfloat)const_int("int_job_application_points_international"); success_needed += ((gfloat)(job->country_rating - country.rating) * (gfloat)const_int("int_job_application_points_per_rating")); } return (user->counters[COUNT_USER_SUCCESS] >= success_needed); } /** Remove a job from the jobs array. @param free Whether to free memory occupied by the job and its team. */ void job_remove(Job *job, gboolean free_tm) { #ifdef DEBUG printf("job_remove\n"); #endif gint i; for(i=0;ilen;i++) if(&g_array_index(jobs, Job, i) == job) { free_job(job, free_tm); g_array_remove_index(jobs, i); break; } } /** Change the game so that the country is used that's specified in the job. */ void job_change_country(Job *job) { #ifdef DEBUG printf("job_change_country\n"); #endif gint i, j, k; Team tm = *(job_get_team(job)); gint season_temp = season + 1; for(i=transfer_list->len - 1;i>=0;i--) transfer_remove_player(i); free_bets(TRUE); /* There's only one user (otherwise international job offers are disabled). */ for(i=0;i<2;i++) { g_array_free(usr(0).bets[i], TRUE); usr(0).bets[i] = g_array_new(FALSE, FALSE, sizeof(BetUser)); } live_game_reset(&usr(0).live_game, NULL, FALSE); free_country(&country, TRUE); xml_country_read(job->country_file, &country); stat5 = STATUS_GENERATE_TEAMS; for(i=0;ilen;i++) for(j=0;jlen;j++) if(strcmp(g_array_index(lig(i).teams, Team, j).name, tm.name) != 0) team_generate_players_stadium(&g_array_index(lig(i).teams, Team, j), 0); else { tm.id = g_array_index(lig(i).teams, Team, j).id; tm.clid = g_array_index(lig(i).teams, Team, j).clid; job->team_id = tm.id; free_team(&g_array_index(lig(i).teams, Team, j)); g_array_index(lig(i).teams, Team, j) = tm; for(k=0;klen;k++) g_array_index(g_array_index(lig(i).teams, Team, j).players, 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 in the start_new_season function don't get applied. */ season = 1; start_new_season(); season = season_temp; }