<URL: http://bugs.freeciv.org/Ticket/Display.html?id=39991 >

I think neither of these bugs may be easy to solve.

> [EMAIL PROTECTED] - Sat Dec 29 03:13:49 2007]:
> Version:  Freeciv 2.1.1
> Client crash bug 1: (SDL AND GTK)
>    During the end-of-turn processing, you can still click on things on
> the
> screen.  Have a long list on the message window from the last turn.
> Before
> this list is refreshed at the beginning of the next turn, double-click
> one of
> the messages near the bottom, which would normally take you to a city
> or unit.
> If the message list on the next turn is shorter, this will trigger an
> assertion
> failure.  I think messages in the queue should be quietly discarded
> when the
> message window is cleared.

The queue is stored in the gtk events and I think there is no simple way
to discard it.  A first step is to see what the assertion is and fix or
remove that.  Long-term the solution may be to save all old messages
(previous turn's messages are useful to scroll back to...).

Can you tell us the assertion that is failing?  Or even better, send a
backtrace after the crash?

> Client reporting bug 1: (SDL) - This appears to work as expected for
>    I have researched all tech and I am working on Future Tech.  One of
> my units
> encounters a hut and the report is:
>         Learned Future Tech 2.  Researching Future Tech 3.
>         You found Future Tech 3 in ancient scrolls of wisdom.
>    I had been researching Future Tech 2.  The research is now Future
> Tech 3.
> It looks like the second line is reporting one tech level too high.
> I have not tested these with version 2.1.2 yet.

This one is also not easy to fix properly, because giving a random tech
is an atomic function and because of the hackish way future techs work.
 The function call is give_random_free_tech which picks and assigns the
text.  On its return the tech name can be determined.  But because the
future tech count has already been incremented by this time the name for
the tech will be wrong.

There are a couple not-as-easy ways this could be fixed.  The attached
patch breaks up give_random_free_tech, removing it completely and
integrating its parts into the 2 callers.  We can therefore get the name
before the tech is assigned.

An alternative would be passing a string pointer (char**) parameter to
give_random_free_tech.  This could then fill in the tech name.  This
doesn't lend itself to future techs as "Future tech %d" is not a string
already allocated.  A second problem is with translation if multiple
translations are to be sent to the clients, or if they are to receive a
pre-translated version.

Yet a third alternative is to redesign the future-tech system to be more
sane.  But I don't know what form this would take.


Index: server/unittools.c
--- server/unittools.c	(revision 14241)
+++ server/unittools.c	(working copy)
@@ -2152,22 +2152,26 @@
   struct player *pplayer = unit_owner(punit);
   Tech_type_id new_tech;
   const char* tech_name;
-  new_tech = give_random_free_tech(pplayer);
+  new_tech = pick_random_tech(pplayer);
   tech_name = advance_name_for_player(pplayer, new_tech);
   notify_player(pplayer, punit->tile, E_HUT_TECH,
 		   _("You found %s in ancient scrolls of wisdom."),
-  script_signal_emit("tech_researched", 3,
-		     API_TYPE_TECH_TYPE, &advances[new_tech],
-		     API_TYPE_PLAYER, pplayer,
-		     API_TYPE_STRING, "hut");
   notify_embassies(pplayer, NULL, NULL, E_TECH_GAIN,
 		   _("The %s have acquired %s"
 		     " from ancient scrolls of wisdom."),
+  do_free_cost(pplayer, new_tech);
+  found_new_tech(pplayer, new_tech, FALSE, TRUE);
+  script_signal_emit("tech_researched", 3,
+		     API_TYPE_TECH_TYPE, &advances[new_tech],
+		     API_TYPE_PLAYER, pplayer,
+		     API_TYPE_STRING, "hut");
Index: server/techtools.c
--- server/techtools.c	(revision 14241)
+++ server/techtools.c	(working copy)
@@ -622,7 +622,7 @@
   Gives a player random tech, which he hasn't researched yet.
-  Returns the tech. This differs from give_random_free_tech - it doesn't
+  Returns the tech. This differs from give_immediate_free_tech - it doesn't
   apply free cost
 Tech_type_id give_random_initial_tech(struct player* pplayer)
@@ -784,27 +784,16 @@
-  Gives a player random tech, which he hasn't researched yet. Applies freecost
-  Returns the tech.
-Tech_type_id give_random_free_tech(struct player* pplayer)
-  Tech_type_id tech;
-  tech = pick_random_tech(pplayer);
-  do_free_cost(pplayer, tech);
-  found_new_tech(pplayer, tech, FALSE, TRUE);
-  return tech;
   Gives a player immediate free tech. Applies freecost
 Tech_type_id give_immediate_free_tech(struct player* pplayer)
   Tech_type_id tech;
   if (get_player_research(pplayer)->researching == A_UNSET) {
-    return give_random_free_tech(pplayer);
+    tech = pick_random_tech(pplayer);
+    do_free_cost(pplayer, tech);
+    found_new_tech(pplayer, tech, FALSE, TRUE);
+    return tech;
   tech = get_player_research(pplayer)->researching;
   do_free_cost(pplayer, tech);
Index: server/techtools.h
--- server/techtools.h	(revision 14241)
+++ server/techtools.h	(working copy)
@@ -32,7 +32,6 @@
 Tech_type_id steal_a_tech(struct player *pplayer, struct player *target,
                 Tech_type_id preferred);
-Tech_type_id give_random_free_tech(struct player *pplayer);
 Tech_type_id give_immediate_free_tech(struct player *pplayer);
 void give_initial_techs(struct player* plr);
 Tech_type_id give_random_initial_tech(struct player* pplayer);
Freeciv-dev mailing list

Reply via email to