<URL: http://bugs.freeciv.org/Ticket/Display.html?id=18773 >
On 7/21/06, Tommi Björkbacka <[EMAIL PROTECTED]> wrote: > > You can reproduce this problem easily. First buy a random unit and > then put a new unit into worklist. After that try to adjust new unit > to the top of worklist. Result is that you have two indentical units > in worklist. I took a different approach to Tommi's patch. This should be more generic fix, meaning that it fixes all the cases where this bug appears and not only one special case. - ML
diff -Nurd -X.diff_ignore freeciv/client/citydlg_common.c freeciv/client/citydlg_common.c --- freeciv/client/citydlg_common.c 2006-09-07 23:51:33.000000000 +0300 +++ freeciv/client/citydlg_common.c 2007-01-15 20:21:21.000000000 +0200 @@ -765,7 +765,7 @@ /************************************************************************** Set the city current production and the worklist, like it should be. **************************************************************************/ -void city_set_queue(struct city *pcity, struct worklist *pqueue) +bool city_set_queue(struct city *pcity, struct worklist *pqueue) { struct worklist copy; struct city_production target; @@ -776,6 +776,15 @@ worklist API wants it out for reasons unknown. Perhaps someone enjoyed making things more complicated than necessary? So I dance around it. */ if (worklist_peek(©, &target)) { + + if (!city_can_change_build(pcity) + && (target.value != pcity->production.value + || target.is_unit != pcity->production.is_unit)) { + /* We cannot change production to one from worklist. + * Do not replace old worklist with new one. */ + return FALSE; + } + worklist_advance(©); city_set_worklist(pcity, ©); @@ -788,6 +797,8 @@ city_set_worklist(pcity, ©); } } + + return TRUE; } /************************************************************************** diff -Nurd -X.diff_ignore freeciv/client/citydlg_common.h freeciv/client/citydlg_common.h --- freeciv/client/citydlg_common.h 2006-07-17 23:56:48.000000000 +0300 +++ freeciv/client/citydlg_common.h 2007-01-15 20:21:35.000000000 +0200 @@ -77,7 +77,7 @@ bool city_queue_insert_worklist(struct city *pcity, int position, struct worklist *worklist); void city_get_queue(struct city *pcity, struct worklist *pqueue); -void city_set_queue(struct city *pcity, struct worklist *pqueue); +bool city_set_queue(struct city *pcity, struct worklist *pqueue); bool city_can_buy(const struct city *pcity); int city_sell_improvement(struct city *pcity, Impr_type_id sell_id); int city_buy_production(struct city *pcity); diff -Nurd -X.diff_ignore freeciv/client/gui-gtk-2.0/wldlg.c freeciv/client/gui-gtk-2.0/wldlg.c --- freeciv/client/gui-gtk-2.0/wldlg.c 2006-07-17 23:56:49.000000000 +0300 +++ freeciv/client/gui-gtk-2.0/wldlg.c 2007-01-15 20:35:41.000000000 +0200 @@ -1464,7 +1464,11 @@ /* dance around worklist braindamage. */ if (ptr->pcity) { - city_set_queue(ptr->pcity, &queue); + if (!city_set_queue(ptr->pcity, &queue)) { + /* Failed to change worklist. This means worklist visible + * on screen is not true. */ + refresh_worklist(ptr->editor); + } } else { copy_worklist(pwl, &queue); } diff -Nurd -X.diff_ignore freeciv/common/city.c freeciv/common/city.c --- freeciv/common/city.c 2006-07-25 13:42:32.000000000 +0300 +++ freeciv/common/city.c 2007-01-15 19:30:02.000000000 +0200 @@ -533,6 +533,14 @@ &get_specialist(type)->reqs); } +/**************************************************************************** + Returns TRUE iff if the given city can change what it is building +****************************************************************************/ +bool city_can_change_build(const struct city *pcity) +{ + return !pcity->did_buy || pcity->shield_stock <= 0; +} + /************************************************************************** Returns how many thousand citizen live in this city. **************************************************************************/ diff -Nurd -X.diff_ignore freeciv/common/city.h freeciv/common/city.h --- freeciv/common/city.h 2006-07-17 23:56:44.000000000 +0300 +++ freeciv/common/city.h 2007-01-15 19:20:57.000000000 +0200 @@ -398,6 +398,7 @@ bool include_shield_stock); int city_turns_to_grow(const struct city *pcity); bool city_can_grow_to(const struct city *pcity, int pop_size); +bool city_can_change_build(const struct city *pcity); /* textual representation of buildings */ diff -Nurd -X.diff_ignore freeciv/common/worklist.c freeciv/common/worklist.c --- freeciv/common/worklist.c 2006-07-17 23:56:46.000000000 +0300 +++ freeciv/common/worklist.c 2007-01-15 20:13:01.000000000 +0200 @@ -75,7 +75,8 @@ /**************************************************************** Fill in the id and is_unit values for the ith element in the - worklist. If the worklist has fewer than i elements, return 0. + worklist. If the worklist has fewer than idx elements, + return FALSE. ****************************************************************/ bool worklist_peek_ith(const struct worklist *pwl, struct city_production *prod, int idx) diff -Nurd -X.diff_ignore freeciv/server/cityhand.c freeciv/server/cityhand.c --- freeciv/server/cityhand.c 2006-07-17 23:56:22.000000000 +0300 +++ freeciv/server/cityhand.c 2007-01-15 19:31:44.000000000 +0200 @@ -357,7 +357,7 @@ } if (!is_build_id_unit_id && !can_build_improvement(pcity, build_id)) return; - if (pcity->did_buy && pcity->shield_stock > 0) { + if (!city_can_change_build(pcity)) { notify_player(pplayer, pcity->tile, E_BAD_COMMAND, _("You have bought this turn, can't change.")); return;
_______________________________________________ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev