Index: client/packhand.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v retrieving revision 1.196 diff -u -b -r1.196 packhand.c --- client/packhand.c 2001/10/18 16:45:31 1.196 +++ client/packhand.c 2001/11/28 16:10:55 @@ -2086,6 +2086,7 @@ game.rgame.nuke_contamination = packet->nuke_contamination; game.rgame.granary_food_ini = packet->granary_food_ini; game.rgame.granary_food_inc = packet->granary_food_inc; + game.rgame.tech_cost_style = packet->tech_cost_style; } /************************************************************************** Index: client/gui-gtk/repodlgs.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/client/gui-gtk/repodlgs.c,v retrieving revision 1.41 diff -u -b -r1.41 repodlgs.c --- client/gui-gtk/repodlgs.c 2001/10/09 18:57:00 1.41 +++ client/gui-gtk/repodlgs.c 2001/11/28 16:10:56 @@ -453,6 +453,10 @@ - game.num_tech_types); data=text; } + my_snprintf(text, sizeof(text), "%s (%d)", + data, + tech_cost(game.player_ptr,GPOINTER_TO_INT(g_list_nth_data(sorting_list, i)))); + data = text; item = gtk_menu_item_new_with_label(data); gtk_menu_append(GTK_MENU(popupmenu), item); @@ -503,7 +507,10 @@ gchar *data = advances[GPOINTER_TO_INT(g_list_nth_data(sorting_list, i))].name; - item = gtk_menu_item_new_with_label(data); + my_snprintf(text, sizeof(text), "%s (%d)", + data, + goal_tech_cost(game.player_ptr,GPOINTER_TO_INT(g_list_nth_data(sorting_list, i)))); + item = gtk_menu_item_new_with_label(text); gtk_menu_append(GTK_MENU(goalmenu), item); gtk_signal_connect(GTK_OBJECT(item), "activate", GTK_SIGNAL_FUNC(science_goal_callback), Index: server/ruleset.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/server/ruleset.c,v retrieving revision 1.82 diff -u -b -r1.82 ruleset.c --- server/ruleset.c 2001/10/26 07:33:23 1.82 +++ server/ruleset.c 2001/11/28 16:10:56 @@ -2195,6 +2195,15 @@ game.rgame.granary_food_inc); game.rgame.granary_food_inc = 100; } + game.rgame.tech_cost_style = + secfile_lookup_int(&file, "civstyle.tech_cost_style"); + if (game.rgame.tech_cost_style<0 || + game.rgame.tech_cost_style>3) { + freelog(LOG_ERROR, "Bad value %i for tech_cost_style. Using 0.", + game.rgame.tech_cost_style); + game.rgame.tech_cost_style = 0; + } + /* * Load global initial techs @@ -2523,6 +2532,7 @@ misc_p.nuke_contamination = game.rgame.nuke_contamination; misc_p.granary_food_ini = game.rgame.granary_food_ini; misc_p.granary_food_inc = game.rgame.granary_food_inc; + misc_p.tech_cost_style = game.rgame.tech_cost_style; assert(sizeof(misc_p.global_init_techs) == sizeof(game.rgame.global_init_techs)); Index: common/capstr.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/capstr.c,v retrieving revision 1.89 diff -u -b -r1.89 capstr.c --- common/capstr.c 2001/10/12 12:22:18 1.89 +++ common/capstr.c 2001/11/28 16:10:56 @@ -71,7 +71,7 @@ */ #define CAPABILITY "+1.11.6 conn_info pop_cost turn attributes new_bonus_tech"\ -" fund_added processing_packets angrycitizen tile_trade init_techs" +" fund_added processing_packets angrycitizen tile_trade init_techs tech_cost" /* "+1.11.6" is protocol for 1.11.6 beta release. Index: common/game.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/game.c,v retrieving revision 1.113 diff -u -b -r1.113 game.c --- common/game.c 2001/11/23 17:27:07 1.113 +++ common/game.c 2001/11/28 16:10:57 @@ -420,7 +420,7 @@ int research_time(struct player *pplayer) { int timemod=(game.year>0) ? 2:1; - return timemod*pplayer->research.researchpoints*game.researchcost; + return timemod*tech_cost(pplayer, pplayer->research.researching); } /************************************************************************** Index: common/game.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/game.h,v retrieving revision 1.90 diff -u -b -r1.90 game.h --- common/game.h 2001/10/26 07:33:23 1.90 +++ common/game.h 2001/11/28 16:10:57 @@ -184,6 +184,7 @@ int nuke_contamination; int granary_food_ini; int granary_food_inc; + int tech_cost_style; /* * Advances given to all players at game start. Index: common/packets.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/packets.c,v retrieving revision 1.166 diff -u -b -r1.166 packets.c --- common/packets.c 2001/10/18 16:45:32 1.166 +++ common/packets.c 2001/11/28 16:10:58 @@ -3754,6 +3754,9 @@ cptr=put_uint8(cptr, packet->nuke_contamination); cptr=put_uint8(cptr, packet->granary_food_ini); cptr=put_uint8(cptr, packet->granary_food_inc); + if (has_capability("tech_cost", pc->capability)) { + cptr=put_uint8(cptr, packet->tech_cost_style); + } if (has_capability("init_techs", pc->capability)) { cptr = put_tech_list(cptr, packet->global_init_techs); } @@ -3784,6 +3787,9 @@ iget_uint8(&iter, &packet->nuke_contamination); iget_uint8(&iter, &packet->granary_food_ini); iget_uint8(&iter, &packet->granary_food_inc); + if (has_capability("tech_cost", pc->capability)) { + iget_uint8(&iter, &packet->tech_cost_style); + } if (has_capability("init_techs", pc->capability)) { iget_tech_list(&iter, packet->global_init_techs); } Index: common/packets.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/packets.h,v retrieving revision 1.98 diff -u -b -r1.98 packets.h --- common/packets.h 2001/10/18 16:45:33 1.98 +++ common/packets.h 2001/11/28 16:10:58 @@ -787,6 +787,7 @@ int nuke_contamination; int granary_food_ini; int granary_food_inc; + int tech_cost_style; int global_init_techs[MAX_NUM_TECH_LIST]; }; Index: common/tech.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/tech.c,v retrieving revision 1.29 diff -u -b -r1.29 tech.c --- common/tech.c 2001/09/06 21:23:08 1.29 +++ common/tech.c 2001/11/28 16:10:58 @@ -16,6 +16,7 @@ #include #include "game.h" +#include "log.h" #include "player.h" #include "support.h" #include "shared.h" /* ARRAY_SIZE */ @@ -231,4 +232,123 @@ return 999; return ((research_time(pplayer) + res - 1) / res); +} + +/************************************************************************** + Count cost for technology recursively. + Do no call this function directly, use tech_cost instead. + Result is researchcost*(1+numparents) +**************************************************************************/ +static int tech_cost_rec(struct player *pplayer, Tech_Type_id tech) +{ + int price = game.researchcost; + if (tech == A_NONE) + return 0; + if (advances[tech].cost != 0) /* Precalculated value */ + return advances[tech].cost; + + price += tech_cost_rec(pplayer, advances[tech].req[0]); + price += tech_cost_rec(pplayer, advances[tech].req[1]); + advances[tech].cost = price; + return price; +} + +/************************************************************************** + Function to determine cost for technology. + Equation is determined from game.rgame.tech_cost_style + 0 == Civ (I|II) style. Every tech increases cost by game.researchcost. + 1 == Cost is game.researchcost*(1+numparenttechs). + 2 == Cost is (numplayers-civswithtech)/numplayers*costinstyle1 + 3 == Cost is (numplayers-civsincontactwithtech)/numplayers*costinstyle1 +**************************************************************************/ +int tech_cost(struct player *pplayer, Tech_Type_id tech) +{ + if (tech > game.num_tech_types) /* Future tech */ + return pplayer->research.researchpoints * game.researchcost; + + switch (game.rgame.tech_cost_style) { + case 0: + return pplayer->research.researchpoints * game.researchcost; + case 1: + { + return tech_cost_rec(pplayer, tech); + } + case 2: + { + int players = get_num_human_and_ai_players(); + int mul = 10 * (players - game.global_advances[tech]) / players; + + return mul * tech_cost_rec(pplayer, tech) / 10; + } + case 3: + { + int playerswithtech = 0; + int players = get_num_human_and_ai_players(); + int mul; + + players_iterate(other) { /* Find out how many players have tech */ + if (!player_has_embassy(pplayer, other)) + continue; + + if (other->research.inventions[tech] == TECH_KNOWN) + ++playerswithtech; + } + players_iterate_end; + + mul = 10 * (players - playerswithtech) / players; + return mul * tech_cost_rec(pplayer, tech) / 10; + } + default: + freelog(LOG_ERROR, "Invalid tech_cost_style %d", game.rgame.tech_cost_style); + return 0; + } +} + +/************************************************************************** + Recursively count cost to goal technology. +**************************************************************************/ +static int goal_tech_cost_rec(struct player *pplayer, Tech_Type_id goal) +{ + int price = 0; + if (goal == A_NONE) + return 0; + + if (pplayer->research.inventions[goal] == TECH_KNOWN) + return 0; + + price += goal_tech_cost_rec(pplayer, advances[goal].req[0]); + price += goal_tech_cost_rec(pplayer, advances[goal].req[1]); + + price += tech_cost(pplayer, goal); + + return price; +} + +/************************************************************************** + Function to determine cost of reaching goal technology. + Uses tech_goal to do calculation except with tech_cost_style == 0. +**************************************************************************/ +int goal_tech_cost(struct player *pplayer, Tech_Type_id goal) +{ + switch (game.rgame.tech_cost_style) { + case 0: + { + int turns = tech_goal_turns(pplayer, goal); + int i; + int cost = pplayer->research.researchpoints * game.researchcost * turns; + for (i = 0; i < turns; ++i) { + cost += game.researchcost * i; + } + return cost; + } + case 1: + case 2: + case 3: + { + return goal_tech_cost_rec(pplayer, goal); + } + default: + freelog(LOG_ERROR, "Invalid tech_cost_style %d", game.rgame.tech_cost_style); + return 0; + } } Index: common/tech.h =================================================================== RCS file: /home/freeciv/CVS/freeciv/common/tech.h,v retrieving revision 1.24 diff -u -b -r1.24 tech.h --- common/tech.h 2001/09/08 12:54:53 1.24 +++ common/tech.h 2001/11/28 16:10:58 @@ -69,6 +69,8 @@ char *helptext; /* Message displayed to the first player to get a bonus tech */ char *bonus_message; + /* Cost of advance in bulbs. Used when tech_cost_style != 0. */ + int cost; }; int get_invention(struct player *plr, int tech); @@ -84,6 +86,8 @@ enum tech_flag_id tech_flag_from_str(char *s); int find_tech_by_flag(int index, enum tech_flag_id flag); int tech_turns_to_advance(struct player *pplayer); +int tech_cost(struct player *pplayer, Tech_Type_id tech); +int goal_tech_cost(struct player *pplayer, Tech_Type_id goal); extern struct advance advances[]; Index: ai/advmilitary.c =================================================================== RCS file: /home/freeciv/CVS/freeciv/ai/advmilitary.c,v retrieving revision 1.79 diff -u -b -r1.79 advmilitary.c --- ai/advmilitary.c 2001/09/15 15:31:17 1.79 +++ ai/advmilitary.c 2001/11/28 16:10:58 @@ -499,7 +499,7 @@ } else if (k > 0 && (shore || m == LAND_MOVING) && unit_types[i].tech_requirement != A_LAST) { if (m == LAND_MOVING) { j *= pcity->ai.wallvalue; j /= 10; } - l = k * (k + pplayer->research.researchpoints) * game.researchcost / + l = goal_tech_cost(pplayer, unit_types[i].tech_requirement) / (game.year > 0 ? 2 : 4); /* cost (shield equiv) of gaining these techs */ l /= city_list_size(&pplayer->cities); /* Katvrr advises that with danger high, l should be weighted more heavily */ @@ -561,9 +561,8 @@ (k || !can_build_unit_direct(pcity, unit_types[i].obsoleted_by)) && unit_types[i].attack_strength && /* otherwise we get SIGFPE's */ m == movetype) { /* I don't think I want the duplication otherwise -- Syela */ - l = k * (k + pplayer->research.researchpoints) * game.researchcost; - if (game.year > 0) l /= 2; - else l /= 4; /* cost (shield equiv) of gaining these techs */ + l = goal_tech_cost(pplayer, unit_types[i].tech_requirement) / + (game.year > 0 ? 2 : 4); /* cost (shield equiv) of gaining these techs */ l /= city_list_size(&pplayer->cities); /* Katvrr advises that with danger high, l should be weighted more heavily */