[Freeciv-Dev] (PR#11610) Two fairness issues with techlevel>0 and techco
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=11610 >
This is a version for S2_0.
The bug with techlevel > 0 is probably the reason of many cases when
team research is desynchronized.
--
mateusz
Index: server/barbarian.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/barbarian.c,v
retrieving revision 1.79.2.4
diff -u -r1.79.2.4 barbarian.c
--- server/barbarian.c 23 Aug 2005 08:05:37 -0000 1.79.2.4
+++ server/barbarian.c 19 Sep 2005 08:55:56 -0000
@@ -141,7 +141,8 @@
barbarians->ai.barbarian_type = SEA_BARBARIAN;
}
set_ai_level_directer(barbarians, game.skill_level);
- init_tech(barbarians, game.tech);
+ init_tech(barbarians);
+ give_initial_techs(barbarians);
/* Ensure that we are at war with everyone else */
players_iterate(pplayer) {
Index: server/plrhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/plrhand.c,v
retrieving revision 1.330.2.38
diff -u -r1.330.2.38 plrhand.c
--- server/plrhand.c 13 Sep 2005 08:43:33 -0000 1.330.2.38
+++ server/plrhand.c 19 Sep 2005 08:56:14 -0000
@@ -64,6 +64,7 @@
static Nation_Type_id pick_available_nation(Nation_Type_id *choices);
static void tech_researched(struct player* plr);
static bool choose_goal_tech(struct player *plr);
+static Tech_Type_id pick_random_tech(struct player *plr);
static enum plr_info_level player_info_level(struct player *plr,
struct player *receiver);
@@ -482,9 +483,10 @@
/* Avoid unnecessary recursion. */
return;
}
+
players_iterate(aplayer) {
if (plr != aplayer
- && plr->diplstates[aplayer->player_no].type == DS_TEAM
+ && players_on_same_team(aplayer, plr)
&& aplayer->is_alive
&& get_invention(aplayer, tech_found) != TECH_KNOWN) {
if (tech_exists(plr->research.researching)) {
@@ -605,12 +607,42 @@
}
/**************************************************************************
+ Returns random researchable tech or A_FUTURE.
+ No side effects
+**************************************************************************/
+static Tech_Type_id pick_random_tech(struct player *plr)
+{
+ int researchable, chosen;
+
+ researchable = 0;
+ tech_type_iterate(i) {
+ if (get_invention(plr, i) == TECH_REACHABLE) {
+ researchable++;
+ }
+ } tech_type_iterate_end;
+
+ if (researchable == 0) {
+ return A_FUTURE;
+ }
+ chosen = myrand(researchable) + 1;
+
+ tech_type_iterate(i) {
+ if (get_invention(plr, i) == TECH_REACHABLE) {
+ chosen--;
+ if (chosen == 0) {
+ return i;
+ }
+ }
+ } tech_type_iterate_end;
+ assert(0);
+ return A_NONE;
+}
+
+/**************************************************************************
...
**************************************************************************/
void choose_random_tech(struct player *plr)
{
- int chosen, researchable = 0;
-
if (plr->research.researching != A_UNSET) {
freelog(LOG_ERROR, "Error: choose_random_tech should only be called "
"when research target is A_UNSET. Please report this "
@@ -618,26 +650,8 @@
}
do {
- tech_type_iterate(i) {
- if (get_invention(plr, i) == TECH_REACHABLE) {
- researchable++;
- }
- } tech_type_iterate_end;
- if (researchable == 0) {
- choose_tech(plr, A_FUTURE);
- return;
- }
- chosen = myrand(researchable) + 1;
-
- tech_type_iterate(i) {
- if (get_invention(plr, i) == TECH_REACHABLE) {
- chosen--;
- if (chosen == 0) {
- choose_tech(plr, i);
- break;
- }
- }
- } tech_type_iterate_end;
+ Tech_Type_id tech = pick_random_tech(plr);
+ choose_tech(plr, tech);
} while (plr->research.researching == A_UNSET);
}
@@ -684,13 +698,10 @@
}
/**************************************************************************
-...
+ Initializes tech data for the player
**************************************************************************/
-void init_tech(struct player *plr, int tech)
+void init_tech(struct player *plr)
{
- int i;
- struct nation_type *nation = get_nation_by_plr(plr);
-
tech_type_iterate(i) {
set_invention(plr, i, TECH_UNKNOWN);
} tech_type_iterate_end;
@@ -698,6 +709,20 @@
plr->research.techs_researched = 1;
+ /* Mark the reachable techs */
+ update_research(plr);
+ if (!choose_goal_tech(plr)) {
+ choose_random_tech(plr);
+ }
+}
+
+/**************************************************************************
+ Gives initial techs to the player
+**************************************************************************/
+void give_initial_techs(struct player* plr)
+{
+ struct nation_type *nation = get_nation_by_plr(plr);
+ int i;
/*
* Give game wide initial techs
*/
@@ -705,7 +730,7 @@
if (game.rgame.global_init_techs[i] == A_LAST) {
break;
}
- set_invention(plr, game.rgame.global_init_techs[i], TECH_KNOWN);
+ found_new_tech(plr, game.rgame.global_init_techs[i], FALSE, TRUE, A_NONE);
}
/*
@@ -715,20 +740,21 @@
if (nation->init_techs[i] == A_LAST) {
break;
}
- set_invention(plr, nation->init_techs[i], TECH_KNOWN);
- }
-
- for (i = 0; i < tech; i++) {
- update_research(plr);
- choose_random_tech(plr); /* could be choose_goal_tech -- Syela */
- set_invention(plr, plr->research.researching, TECH_KNOWN);
+ found_new_tech(plr, nation->init_techs[i], FALSE, TRUE, A_NONE);
}
+}
- /* Mark the reachable techs */
- update_research(plr);
- if (!choose_goal_tech(plr)) {
- choose_random_tech(plr);
- }
+/**************************************************************************
+ Gives a player random tech, which he hasn't researched yet.
+ Returns the tech. Does not apply free cost.
+**************************************************************************/
+Tech_Type_id give_random_initial_tech(struct player* pplayer)
+{
+ Tech_Type_id tech;
+
+ tech = pick_random_tech(pplayer);
+ found_new_tech(pplayer, tech, FALSE, TRUE, A_NONE);
+ return TRUE;
}
/**************************************************************************
Index: server/plrhand.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/plrhand.h,v
retrieving revision 1.69.2.1
diff -u -r1.69.2.1 plrhand.h
--- server/plrhand.h 6 Jul 2005 08:17:33 -0000 1.69.2.1
+++ server/plrhand.h 19 Sep 2005 08:56:14 -0000
@@ -66,11 +66,13 @@
bool saving_bulbs, int next_tech);
void found_new_future_tech(struct player *pplayer);
void update_tech(struct player *plr, int bulbs);
-void init_tech(struct player *plr, int tech);
+void init_tech(struct player *plr);
void choose_random_tech(struct player *plr);
void choose_tech(struct player *plr, int tech);
void choose_tech_goal(struct player *plr, int tech);
void get_a_tech(struct player *pplayer, struct player *target);
+void give_initial_techs(struct player* plr);
+Tech_Type_id give_random_initial_tech(struct player* pplayer);
void send_player_turn_notifications(struct conn_list *dest);
Index: server/savegame.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/savegame.c,v
retrieving revision 1.197.2.19
diff -u -r1.197.2.19 savegame.c
--- server/savegame.c 23 Aug 2005 08:30:23 -0000 1.197.2.19
+++ server/savegame.c 19 Sep 2005 08:56:34 -0000
@@ -1662,7 +1662,8 @@
}
/* Add techs from game and nation, but ignore game.tech. */
- init_tech(plr, 0);
+ init_tech(plr);
+ give_initial_techs(plr);
/* not all players have teams */
if (section_file_lookup(file, "player%d.team", plrno)) {
Index: server/srv_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/srv_main.c,v
retrieving revision 1.201.2.12
diff -u -r1.201.2.12 srv_main.c
--- server/srv_main.c 15 Aug 2005 03:33:28 -0000 1.201.2.12
+++ server/srv_main.c 19 Sep 2005 08:56:34 -0000
@@ -1819,10 +1819,33 @@
players_iterate(pplayer) {
player_map_allocate(pplayer);
- init_tech(pplayer, game.tech);
+ init_tech(pplayer);
player_limit_to_government_rates(pplayer);
pplayer->economic.gold = game.gold;
} players_iterate_end;
+
+ players_iterate(pplayer) {
+ int i;
+ bool free_techs_already_given = FALSE;
+
+ give_initial_techs(pplayer);
+
+ players_iterate(eplayer) {
+ if (players_on_same_team(eplayer, pplayer) &&
+ eplayer->player_no < pplayer->player_no) {
+ free_techs_already_given = TRUE;
+ break;
+ }
+ } players_iterate_end;
+
+ if (free_techs_already_given) {
+ break;
+ }
+ for (i = 0; i < game.tech; i++) {
+ give_random_initial_tech(pplayer);
+ }
+ } players_iterate_end;
+
if(game.is_new_game) {
/* If we're starting a new game, reset the max_players to be the
* number of players currently in the game. But when loading a game
Index: server/stdinhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/stdinhand.c,v
retrieving revision 1.354.2.40
diff -u -r1.354.2.40 stdinhand.c
--- server/stdinhand.c 1 Sep 2005 19:52:57 -0000 1.354.2.40
+++ server/stdinhand.c 19 Sep 2005 08:56:34 -0000
@@ -2709,7 +2709,8 @@
if ((server_state == RUN_GAME_STATE) || !game.is_new_game) {
pplayer->nation = OBSERVER_NATION;
- init_tech(pplayer, 0);
+ init_tech(pplayer);
+ give_initial_techs(pplayer);
map_know_and_see_all(pplayer);
}
|
|