[Freeciv-Dev] (PR#40591) [Patch] Make tired attack a ruleset option
http://bugs.freeciv.org/Ticket/Display.html?id=40591 > A number of players do not appreciate the removal of the "tired" attack penalty (units attack strength reduced if they attack with 1/3 or 2/3 moves left), including myself. When I brought this up on the longturn site, http://www.longturn.org/ltxiv#comment-6674 it was generally agreed that there should be at least some kind of option to allow the old behaviour, if server operators/ruleset makers desire it. So the attached patch makes the proper minimal additions to the combat and ruleset code for 2.2, introducting a combat_rules.tired_attack field in the game.ruleset file and updating packet definitions. The civ1, civ2, and default rulesets are also updated to make use of the field (enabled, enabled, and disabled respectively). --- 行け!弛み無くて死なない戦士。 common/combat.c |4 common/game.h |2 ++ common/packets.def|1 + data/civ1/game.ruleset|8 +++- data/civ2/game.ruleset|8 +++- data/default/game.ruleset |8 +++- server/ruleset.c |5 + version.in|2 +- 8 files changed, 34 insertions(+), 4 deletions(-) diff --git a/common/combat.c b/common/combat.c index 486ee9a..70432d7 100644 --- a/common/combat.c +++ b/common/combat.c @@ -375,6 +375,10 @@ int base_get_attack_power(const struct unit_type *punittype, power = punittype->attack_strength * POWER_FACTOR; power *= punittype->veteran[veteran].power_fact; + if (game.info.tired_attack && moves_left < SINGLE_MOVE) { +power = (power * moves_left) / SINGLE_MOVE; + } + return power; } diff --git a/common/game.h b/common/game.h index 6b83c88..4e75ece 100644 --- a/common/game.h +++ b/common/game.h @@ -210,6 +210,8 @@ bool setting_class_is_changeable(enum sset_class class); #define GAME_DEFAULT_SLOW_INVASIONS TRUE +#define GAME_DEFAULT_TIRED_ATTACKFALSE + #define GAME_DEFAULT_DIPLOMACY 0 #define GAME_MIN_DIPLOMACY 0 #define GAME_MAX_DIPLOMACY 4 diff --git a/common/packets.def b/common/packets.def index 6dec219..60fa2e9 100644 --- a/common/packets.def +++ b/common/packets.def @@ -443,6 +443,7 @@ PACKET_GAME_INFO=15; sc UINT8 tech_leakage; YEAR tech_cost_double_year; BOOL killstack; + BOOL tired_attack; UINT8 upgrade_veteran_loss; UINT8 autoupgrade_veteran_loss; UINT16 incite_improvement_factor; diff --git a/data/civ1/game.ruleset b/data/civ1/game.ruleset index b5940eb..27d70e6 100644 --- a/data/civ1/game.ruleset +++ b/data/civ1/game.ruleset @@ -104,7 +104,13 @@ total_factor = 100 ;not inside a city, fortress or airbase, all units in the same tile are ;destroyed along with the defender. This is the freeciv default. ;If this options is set to 0, only the defender unit is destroyed. -killstack = 1 +killstack = 1 + +;If tired_attack is set to 1, units that attack with only 1/3 or 2/3 moves +;left will have their attack power reduced by 2/3 or 1/3 respectively. If +;this is set to 0 units will attack with full strength even if they have +;only fractional moves left. +tired_attack = 1 [teams] names = diff --git a/data/civ2/game.ruleset b/data/civ2/game.ruleset index 87ab099..c1cdf3c 100644 --- a/data/civ2/game.ruleset +++ b/data/civ2/game.ruleset @@ -98,7 +98,13 @@ total_factor = 100 ;not inside a city, fortress or airbase, all units in the same tile are ;destroyed along with the defender. This is the freeciv default. ;If this options is set to 0, only the defender unit is destroyed. -killstack = 1 +killstack = 1 + +;If tired_attack is set to 1, units that attack with only 1/3 or 2/3 moves +;left will have their attack power reduced by 2/3 or 1/3 respectively. If +;this is set to 0 units will attack with full strength even if they have +;only fractional moves left. +tired_attack = 1 [teams] names = diff --git a/data/default/game.ruleset b/data/default/game.ruleset index d454e90..0d7d4ef 100644 --- a/data/default/game.ruleset +++ b/data/default/game.ruleset @@ -125,7 +125,13 @@ slow_invasions = 1 ;not inside a city, fortress or airbase, all units in the same tile are ;destroyed along with the defender. This is the freeciv default. ;If this options is set to 0, only the defender unit is destroyed. -killstack = 1 +killstack = 1 + +;If tired_attack is set to 1, units that attack with only 1/3 or 2/3 moves +;left will have their attack power reduced by 2/3 or 1/3 respectively. If +;this is set to 0 units will attack with full strength even if they have +;only fractional moves left. +tired_attack = 0 [teams] names = diff --git a/server/ruleset.c b/server/ruleset.c index 01994a8..7cf3784 100644 --- a/server/ruleset.c +++ b/server/ruleset.c @@ -3108,6 +3108,11 @@ static void load_ruleset_game(void) /* Enable/Disable killstack */ game.info.killstack = secfile_lookup_bool(&file, "combat_rules.killstack");
[Freeciv-Dev] (PR#40592) auth backend support
http://bugs.freeciv.org/Ticket/Display.html?id=40592 > > [EMAIL PROTECTED] - Tue Dec 09 00:24:30 2008]: > > auth support is tied to mysql, rather than a generic interface which > could support another backend, such as sqlite or postgres. Yes, I agree, though this would be some work to cleanup the configure and m4 files and redesign the auth.c module. As much as I would like for this to happen, we are kind of short on volunteer coders at the moment... :( --- この俺様にも限界がある。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40593) [Editor] Cleanup editing allowed checks
http://bugs.freeciv.org/Ticket/Display.html?id=40593 > Attached patch reduces code duplication by moving the check whether a connection is allowed to edit out of every server edit handler and into server_packet_input() before the handlers are called. --- 禁転載 common/packets.def | 20 server/edithand.c | 136 +-- server/srv_main.c | 24 - version.in |2 +- 4 files changed, 37 insertions(+), 145 deletions(-) diff --git a/common/packets.def b/common/packets.def index 6dec219..4f69671 100644 --- a/common/packets.def +++ b/common/packets.def @@ -1425,11 +1425,11 @@ PACKET_RULESET_RESOURCE=124;sc,lsend STRING graphic_alt[MAX_LEN_NAME]; end -/** Editing hash packets **/ +/** Client Editor Packets **/ -/* Always keep this as the first edit type packet, - * so that the test in server/srv_main.c +1203 - * is easy to write. */ +/* Always keep this as the first edit type packet sent by + * the client, so that the test in server/srv_main.c in + * the function is_client_edit_packet() is easy to write. */ PACKET_EDIT_MODE=150;cs,handle-per-conn,dsend BOOL state; end @@ -1616,14 +1616,16 @@ PACKET_EDIT_PLAYER_VISION=171;cs,handle-per-conn,dsend UINT8 size; end -PACKET_EDIT_GAME=172;cs,handle-per-conn,handle-via-packet +/* Always keep this as the last edit type packet sent by + * the client, so that the test in server/srv_main.c in + * the function is_client_edit_packet() is easy to write. */ +PACKET_EDIT_GAME=180;cs,handle-per-conn,handle-via-packet YEAR year; end -/* Always keep this as the last edit type packet, - * so that the test in server/srv_main.c +1213 - * is easy to write. */ -PACKET_EDIT_OBJECT_CREATED=173;sc,dsend +/** Server Editor Packets **/ + +PACKET_EDIT_OBJECT_CREATED=181;sc,dsend SINT32 tag; SINT32 id; end diff --git a/server/edithand.c b/server/edithand.c index 04ca03e..3656184 100644 --- a/server/edithand.c +++ b/server/edithand.c @@ -140,12 +140,14 @@ void handle_edit_mode(struct connection *pc, bool is_edit_mode) if (!can_conn_enable_editing(pc)) { return; } + if (!game.info.is_edit_mode && is_edit_mode) { /* Someone could be cheating! Warn people. */ notify_conn(NULL, NULL, E_SETTING, _(" *** Server set to edit mode by %s! *** "), conn_description(pc)); } + if (game.info.is_edit_mode && !is_edit_mode) { notify_conn(NULL, NULL, E_SETTING, _(" *** Edit mode cancelled by %s. *** "), @@ -153,6 +155,7 @@ void handle_edit_mode(struct connection *pc, bool is_edit_mode) check_leaving_edit_mode(); } + if (game.info.is_edit_mode != is_edit_mode) { game.info.is_edit_mode = is_edit_mode; send_game_info(NULL); @@ -172,12 +175,6 @@ void handle_edit_tile_terrain(struct connection *pc, int x, int y, struct terrain *pterrain; struct tile *ptile_center; - if (!can_conn_edit(pc)) { -notify_conn(pc->self, NULL, E_BAD_COMMAND, -_("You are not allowed to edit.")); -return; - } - ptile_center = map_pos_to_tile(x, y); if (!ptile_center) { notify_conn(pc->self, NULL, E_BAD_COMMAND, @@ -219,13 +216,6 @@ void handle_edit_tile_resource(struct connection *pc, int x, int y, struct resource *presource; struct tile *ptile_center; - - if (!can_conn_edit(pc)) { -notify_conn(pc->self, NULL, E_BAD_COMMAND, -_("You are not allowed to edit.")); -return; - } - ptile_center = map_pos_to_tile(x, y); if (!ptile_center) { notify_conn(pc->self, NULL, E_BAD_COMMAND, @@ -258,12 +248,6 @@ void handle_edit_tile_special(struct connection *pc, int x, int y, struct tile *ptile_center; bool changed = FALSE; - if (!can_conn_edit(pc)) { -notify_conn(pc->self, NULL, E_BAD_COMMAND, -_("You are not allowed to edit.")); -return; - } - ptile_center = map_pos_to_tile(x, y); if (!ptile_center) { notify_conn(pc->self, NULL, E_BAD_COMMAND, @@ -308,12 +292,6 @@ void handle_edit_tile_base(struct connection *pc, int x, int y, struct base_type *pbase; bool changed = FALSE; - if (!can_conn_edit(pc)) { -notify_conn(pc->self, NULL, E_BAD_COMMAND, -_("You are not allowed to edit.")); -return; - } - ptile_center = map_pos_to_tile(x, y); if (!ptile_center) { notify_conn(pc->self, NULL, E_BAD_COMMAND, @@ -360,12 +338,6 @@ void handle_edit_tile(struct connection *pc, int id; bool changed = FALSE; - if (!can_conn_edit(pc)) { -notify_conn(pc->self, NULL, E_BAD_COMMAND, -_("You are not allowed to edit.")); -return; - } - id = packet->id; ptile = index_to_tile(id); @@ -425,12 +397,6 @@ void handle_edit_unit_create(struct connection *pc, bool coastal; int id, i
[Freeciv-Dev] (PR#40595) Bug: crash causes loss of automatic movement deference
http://bugs.freeciv.org/Ticket/Display.html?id=40595 > > [EMAIL PROTECTED] - Wed Dec 10 05:35:00 2008]: > > I'm running Ubuntu Linux; I installed Freeciv 2.1.5 as a (Debian, of > course) binary. Since many critical bugs have been fixed since 2.1.5 I would suggest that you upgrade to the latest version as of now (2.1.8). If you find that the crash still occurs then post the backtrace and savegame and I will check it out. (See http://freeciv.wikia.com/wiki/Bug_Reporting for tips on how to make a backtrace.) --- 世界は彼の寂しさで凍っている荒地に変えられてしまった。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40596) [Patch] Generic iterator interface
http://bugs.freeciv.org/Ticket/Display.html?id=40596 > Attached patch adds a generic iterator interface for implementing iteration macros. This framework serves the following purposes: 1. Hide specific container and iterator implementation details from other code modules, in particular remove the need for the iteration macros defined in header files to have access to container internals. 2. Preserve constness of containers when iterating over them, i.e. the container is not modified when using an iteration macro. 3. Reduce code duplication in iteration macros, i.e. have specific iteration macros only change what needs to be changed rather than rewriting the whole loop structure each time. 4. Ensure that iteration over a sequence of N values has O(N) time complexity. The interface is used as follows. Suppose we wish to add iteration macros for the opaque type 'foo'. In foo's header file we add: #include "iterator.h" struct iterator *foo_get_iter(const struct foo *pfoo); #define foo_thing_iterate(pfoo, pthing)\ generic_iterate(foo_get_iter(pfoo), struct thing *, pthing) #define foo_thing_iterate_end generic_iterate_end Then in foo's code module we define a derived iterator type, say 'foo_thing_iterator', which provides implementations for the 4 iterator interface functions next, free, get and valid. The body of foo_get_iter() creates the derived iterator (setting up its "vtable", i.e. function pointers) and returns it as a "base class" iterator pointer. Now we can iterate over foo's things like: #include "foo.h" ... /* Make a foo, add some things. */ foo_thing_iterate(pfoo, pthing) { ... /* Use pthing */ } foo_thing_iterate_end; Now while the 4 goals listed above should be satisfied by this framework, there are some disadvantages to this particular implementation of the system: 1. Iterators are allocated on the heap and free'd after the iteration loop, which is possibly slower than if they were just variables allocated on the stack. 2. The "virtual" functions incur at least an extra pointer dereference when ever they are used. Since there are usually 3 virtual calls per loop iteration, this could be a significant running time overhead. 3. The actual generic_iterate macro body is pretty hairy, using token concatenation and a for-loop syntax hack to allow nesting of itself and to ensure iterators are always free'd. So I'm not sure whether this is really necessary, or whether it is overkill for the purposes of the code base. Anyway I will let it sit a bit for your examination and try out some uses of it in subsequent patches. --- 忘れずに空腹衝動を戻しなさい。 utility/Makefile.am |1 + utility/iterator.h | 92 +++ 2 files changed, 93 insertions(+), 0 deletions(-) diff --git a/utility/Makefile.am b/utility/Makefile.am index 106d87f..5dbbe12 100644 --- a/utility/Makefile.am +++ b/utility/Makefile.am @@ -23,6 +23,7 @@ libcivutility_a_SOURCES = \ inputfile.h \ ioz.c \ ioz.h \ + iterator.h \ log.c \ log.h \ netintf.c \ diff --git a/utility/iterator.h b/utility/iterator.h new file mode 100644 index 000..c701f4e --- /dev/null +++ b/utility/iterator.h @@ -0,0 +1,92 @@ +/*** + Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold + 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, 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. +***/ +#ifndef FC__ITERATOR_H +#define FC__ITERATOR_H + +/*** + Iterator base class. "Derived" iterators must have this struct as + their first member (as a "vtable") and provide implementations of + the "pure virtual" member functions. See the function comment headers + below for the expected behaviour of these functions. +***/ +struct iterator { + void (*next)(struct iterator *it); + void (*free)(struct iterator *it); + void *(*get)(const struct iterator *it); + bool (*valid)(const struct iterator *it); +}; + +#define ITERATOR(p) ((struct iterator *)(p)) + +/*** + Advances the iterator to point to the next item in the sequence. +***/ +static inline void iterator_next(struct iterator *it
[Freeciv-Dev] (PR#40597) [Patch] Improved hash iteration
http://bugs.freeciv.org/Ticket/Display.html?id=40597 > Attached patch improves hash key/value iteration using the iterator interface in 40596. - For convenience three iterate macros are provided for hash tables: for iterating over keys, values, or both. - The implementation of the iterator and hash table is kept in the hash.c module and out of the header. - Code making its own iteration macros based on internal hash tables is simplified. --- あなたの凄い運命をこよなく愛するようになる。 client/editor.c | 12 ++-- client/gui-gtk-2.0/editprop.c | 59 +-- server/edithand.c |4 +- utility/hash.c| 167 +++-- utility/hash.h| 42 +-- 5 files changed, 189 insertions(+), 95 deletions(-) diff --git a/client/editor.c b/client/editor.c index d5b89f8..9cae047 100644 --- a/client/editor.c +++ b/client/editor.c @@ -510,11 +510,11 @@ static void popup_properties(struct tile *ptile) tiles = tile_list_new(); if (editor_tile_is_selected(ptile)) { -hash_iterate(editor->selected_tile_table, sel_tile, dummy) { +hash_keys_iterate(editor->selected_tile_table, sel_tile) { if (can_edit_tile_properties(sel_tile)) { tile_list_append(tiles, sel_tile); } -} hash_iterate_end; +} hash_keys_iterate_end; } else { if (can_edit_tile_properties(ptile)) { tile_list_append(tiles, ptile); @@ -1023,9 +1023,9 @@ void editor_apply_tool_to_selection(void) } connection_do_buffer(&client.conn); - hash_iterate(editor->selected_tile_table, ptile, dummy) { + hash_keys_iterate(editor->selected_tile_table, ptile) { editor_apply_tool(ptile, TRUE); - } hash_iterate_end; + } hash_keys_iterate_end; editor_notify_edit_finished(); connection_do_unbuffer(&client.conn); @@ -1825,11 +1825,11 @@ const struct tile *editor_get_selection_center(void) } origin = map_pos_to_tile(0, 0); - hash_iterate(editor->selected_tile_table, ptile, dummy) { + hash_keys_iterate(editor->selected_tile_table, ptile) { map_distance_vector(&dx, &dy, origin, ptile); xsum += dx; ysum += dy; - } hash_iterate_end; + } hash_keys_iterate_end; cx = xsum / count; cy = ysum / count; diff --git a/client/gui-gtk-2.0/editprop.c b/client/gui-gtk-2.0/editprop.c index 8c0863c..26696f1 100644 --- a/client/gui-gtk-2.0/editprop.c +++ b/client/gui-gtk-2.0/editprop.c @@ -22,6 +22,7 @@ #include "fcintl.h" #include "hash.h" +#include "iterator.h" #include "log.h" #include "mem.h" @@ -539,29 +540,19 @@ static void property_page_remove_creation_tag(struct property_page *pp, static bool property_page_tag_is_known(struct property_page *pp, int tag); static void property_page_clear_tags(struct property_page *pp); -#define property_page_objprop_iterate(ARG_pp, NAME_op) do {\ - struct objprop *NAME_op;\ - if (!(ARG_pp) || !(ARG_pp)->objprop_table) {\ -break;\ - }\ - hash_iterate((ARG_pp)->objprop_table, MY_dummy, MY_value) {\ -NAME_op = MY_value; +static struct iterator * +property_page_get_objprop_iter(const struct property_page *pp); +#define property_page_objprop_iterate(ARG_pp, NAME_op)\ + generic_iterate(property_page_get_objprop_iter(ARG_pp),\ + struct objprop *, NAME_op) +#define property_page_objprop_iterate_end generic_iterate_end -#define property_page_objprop_iterate_end \ - } hash_iterate_end;\ -} while (0) - -#define property_page_objbind_iterate(ARG_pp, NAME_ob) do {\ - struct objbind *NAME_ob;\ - if (!(ARG_pp) || !(ARG_pp)->objbind_table) {\ -break;\ - }\ - hash_iterate((ARG_pp)->objbind_table, MY_dummy, MY_value) {\ -NAME_ob = MY_value; - -#define property_page_objbind_iterate_end \ - } hash_iterate_end;\ -} while (0) +static struct iterator * +property_page_get_objbind_iter(const struct property_page *pp); +#define property_page_objbind_iterate(ARG_pp, NAME_ob)\ + generic_iterate(property_page_get_objbind_iter(ARG_pp),\ + struct objbind *, NAME_ob) +#define property_page_objbind_iterate_end generic_iterate_end / @@ -3685,6 +3676,30 @@ static void property_page_setup_objprops(struct property_page *pp) } / + Return an iterator over the object properties in the property page. +/ +static struct iterator * +property_page_get_objprop_iter(const struct property_page *pp) +{ + if (!pp || !pp->objprop_table) { +return NULL; + } + return hash_get_value_iter(pp->objprop_table); +} + +/ + Return an iterator over the bound objects in the property page. +
[Freeciv-Dev] (PR#40592) auth backend support
http://bugs.freeciv.org/Ticket/Display.html?id=40592 > > [sch...@debian.org - Wed Dec 10 22:50:45 2008]: > > On Wed, Dec 10, 2008 at 01:57:51AM -0800, Jason Dorje Short wrote: > > GGZ provides all the same features as auth with multiple backends > > support. I'd see improving the GGZ support as a better > > alternative than working on auth. > > Thanks, I'll abandon my effort on the auth front. I would rather that if you have the time and would not mind having your work possibly superseded at some unknown later time when ggz has matured, to submit your proposed auth improvements. With a clever design, there is also no reason why ggz cannot become just another "backend" for authenticating users (at least I assume the ggz api would permit that). Not that I do not agree with the premise of ggz, it is just that having multiple auth backends would help in the unification of the various freeciv "flavours". For example longturn freeciv uses a postgres library (pqxx of all things...) so that the server auth can be tied in with drupal modules used on the longturn.org site. Warclient freeciv implements a full extended glicko rating system, which is quite a bit more complex than the rating system provided by ggz given the complexity of game types possible in freeciv. I think server operators should have a choice in how they can authenticate users. Perhaps they just want fine grained control over which users are allowed to connect (e.g. banhammer), and the connection statistics. Or the ggz master servers are down that day. Anyway, my point is that assuming implementing multiple auth backends would not turn the auth code into a sprawling unmaintainable mess, since nobody is actively working on the freeciv-ggz integration at the moment I would that you make your contribution rather than not. --- 皇帝陛下に忠誠をお誓いします! ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40596) [Patch] Generic iterator interface
http://bugs.freeciv.org/Ticket/Display.html?id=40596 > > [book - Thu Dec 11 06:36:54 2008]: > > Attached patch adds a generic iterator interface for > implementing iteration macros. > > [...] > > Now while the 4 goals listed above should be satisfied by > this framework, there are some disadvantages to this > particular implementation of the system: > > [...] I would add to the list of disadvantages that using the 'return' statment in a generic_iterate macro prevents the iterator from being freed. This is a pretty big deal- breaker in my opinion. :( I do have an idea on how to fix 3 of the 4 disadvantages though, so I will try a second version soon. :) --- ああそう。興奮してる。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#17435) island generator connects continents
http://bugs.freeciv.org/Ticket/Display.html?id=17435 > I have confirmed that the island generator (gen 3) will sometimes place islands in a way that there is no ocean between them. I have also tested the patch and it solved the problem in all my tests. Since the code looks fine I will commit it soon (if no objections are raised). Incidentally the patch does actually change the code. To see this let A denote the value of the boolean expression before the patch, and B that of it after. Let I be the value of is_ocean(), U a boolean that is true if the terrain is equal to T_UNKNOWN, and F true if the terrain has the oceanic flag. Thus we have I = !U && F A = !U && !I = !U && !(!U && F) = !U && (!!U || !F) = !U && (U || !F) = (!U && U) || (!U && !F) = false || (!U && !F) = !U && !F B = !I = !(!U && F) = !!U || !F = U || !F != A or in the first case is_near_land() returns TRUE if there is an adjacent tile that is both not unknown and does not have the oceanic flag, while in the second case it returns TRUE if there is an adjacent tile that is either unknown or does not have the oceanic flag. Hence the reason the patch works is because it makes is_near_land() assume unknown tiles could be land. :] --- ド・モルガン先生、ありがとうございました。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40596) [Patch] Generic iterator interface
http://bugs.freeciv.org/Ticket/Display.html?id=40596 > > [book - Thu Dec 11 20:59:58 2008]: > > > [book - Thu Dec 11 06:36:54 2008]: > > > > Attached patch adds a generic iterator interface for > > implementing iteration macros. > > > > [...] > > > > Now while the 4 goals listed above should be satisfied by > > this framework, there are some disadvantages to this > > particular implementation of the system: > > > > [...] > > I would add to the list of disadvantages that using the > 'return' statment in a generic_iterate macro prevents the > iterator from being freed. This is a pretty big deal- > breaker in my opinion. :( > > I do have an idea on how to fix 3 of the 4 disadvantages > though, so I will try a second version soon. :) Alright here is an improved version of the iterator interface that satisfies the four goals in my first post, and solves three (ok 2.5 ;)) of the four mentioned problems. The main change is to use a variation of c++ "placement new" and dynamically allocated stack space for derived iterator types. The memory is allocated using a c99 variable length array whose size is determined by a special 'sizeof' function for each derived iterator. This memory is then passed to a "constructor"-like function which initializes it according to the derived type, and returns a pointer to the iterator base class. So in terms of the previously given example, the foo.h header becomes: #include "iterator.h" struct foo_iter; size_t foo_iter_sizeof(void); struct iterator *foo_iter_init(struct foo_iter *it, const struct foo *pfoo); #define foo_thing_iterate(pfoo, pthing)\ generic_iterate(struct foo_iter, struct thing *, pthing, foo_iter_sizeof, foo_iter_init, pfoo) #define foo_thing_iterate_end generic_iterate_end And in foo.c we would have: struct foo_iter { struct iterator vtable; ... /* Implementation specific data. */ }; size_t foo_iter_sizeof(void) { return sizeof(struct foo_iter); } struct iterator *foo_iter_init(struct foo_iter *it, const struct foo *pfoo) { ... /* Setup vtable and private data. */ return ITERATOR(it); } The iteration macro use remains the same, but now there is no use of malloc/free and it is safe to exit the loop via 'return' (as well as nesting the macro as before). I say "2.5" above since the body of the generic_iterate is still rather ugly, making use of a lot of token concatention (to make local variable names unique) and the c99 macro vararg syntax (to allow zero or more extra arguments to the init function). In fact the macro vararg uses the gcc extension that eats the leading comma if there are no args given for '...'. Since this is not strict c99, if this is a problem I can just make at least one argument mandatory. Otherwise the standard c99 macro varargs and the variable length array features are checked for in m4/c99.m4 so I take it that these are safe to use. I'll post an updated version of the hash iterators (40597) making use of this patch so that you can see this interface in action. --- ウーン。それはね、期待していなかった。 utility/Makefile.am |1 + utility/iterator.h | 88 +++ 2 files changed, 89 insertions(+), 0 deletions(-) diff --git a/utility/Makefile.am b/utility/Makefile.am index 106d87f..5dbbe12 100644 --- a/utility/Makefile.am +++ b/utility/Makefile.am @@ -23,6 +23,7 @@ libcivutility_a_SOURCES = \ inputfile.h \ ioz.c \ ioz.h \ + iterator.h \ log.c \ log.h \ netintf.c \ diff --git a/utility/iterator.h b/utility/iterator.h new file mode 100644 index 000..738d019 --- /dev/null +++ b/utility/iterator.h @@ -0,0 +1,88 @@ +/*** + Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold + 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, 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. +***/ +#ifndef FC__ITERATOR_H +#define FC__ITERATOR_H + +/*** + Iterator base class. "Derived" iterators must have this struct as + their first member (as a "vtable") and provide implementations of the + "pure virtual" member functions. See the function comment headers + below for the expected behaviour of these functions. +***/ +struct iterator { + void (*next)(struct iterator *it); + void *(*get)(const struct iterator *it); + bool (*valid)(const str
[Freeciv-Dev] (PR#40597) [Patch] Improved hash iteration
http://bugs.freeciv.org/Ticket/Display.html?id=40597 > > [book - Thu Dec 11 06:52:46 2008]: > > Attached patch improves hash key/value iteration using > the iterator interface in 40596. Here is the version using the second version of the iterator interface. --- これはなかなかいいですね。黄色のはありますか。 client/editor.c | 12 ++-- client/gui-gtk-2.0/editprop.c | 30 ++--- server/edithand.c |4 +- utility/hash.c| 137 ++--- utility/hash.h| 51 --- 5 files changed, 128 insertions(+), 106 deletions(-) diff --git a/client/editor.c b/client/editor.c index d5b89f8..9cae047 100644 --- a/client/editor.c +++ b/client/editor.c @@ -510,11 +510,11 @@ static void popup_properties(struct tile *ptile) tiles = tile_list_new(); if (editor_tile_is_selected(ptile)) { -hash_iterate(editor->selected_tile_table, sel_tile, dummy) { +hash_keys_iterate(editor->selected_tile_table, sel_tile) { if (can_edit_tile_properties(sel_tile)) { tile_list_append(tiles, sel_tile); } -} hash_iterate_end; +} hash_keys_iterate_end; } else { if (can_edit_tile_properties(ptile)) { tile_list_append(tiles, ptile); @@ -1023,9 +1023,9 @@ void editor_apply_tool_to_selection(void) } connection_do_buffer(&client.conn); - hash_iterate(editor->selected_tile_table, ptile, dummy) { + hash_keys_iterate(editor->selected_tile_table, ptile) { editor_apply_tool(ptile, TRUE); - } hash_iterate_end; + } hash_keys_iterate_end; editor_notify_edit_finished(); connection_do_unbuffer(&client.conn); @@ -1825,11 +1825,11 @@ const struct tile *editor_get_selection_center(void) } origin = map_pos_to_tile(0, 0); - hash_iterate(editor->selected_tile_table, ptile, dummy) { + hash_keys_iterate(editor->selected_tile_table, ptile) { map_distance_vector(&dx, &dy, origin, ptile); xsum += dx; ysum += dy; - } hash_iterate_end; + } hash_keys_iterate_end; cx = xsum / count; cy = ysum / count; diff --git a/client/gui-gtk-2.0/editprop.c b/client/gui-gtk-2.0/editprop.c index 8c0863c..9f2454b 100644 --- a/client/gui-gtk-2.0/editprop.c +++ b/client/gui-gtk-2.0/editprop.c @@ -539,29 +539,13 @@ static void property_page_remove_creation_tag(struct property_page *pp, static bool property_page_tag_is_known(struct property_page *pp, int tag); static void property_page_clear_tags(struct property_page *pp); -#define property_page_objprop_iterate(ARG_pp, NAME_op) do {\ - struct objprop *NAME_op;\ - if (!(ARG_pp) || !(ARG_pp)->objprop_table) {\ -break;\ - }\ - hash_iterate((ARG_pp)->objprop_table, MY_dummy, MY_value) {\ -NAME_op = MY_value; - -#define property_page_objprop_iterate_end \ - } hash_iterate_end;\ -} while (0) - -#define property_page_objbind_iterate(ARG_pp, NAME_ob) do {\ - struct objbind *NAME_ob;\ - if (!(ARG_pp) || !(ARG_pp)->objbind_table) {\ -break;\ - }\ - hash_iterate((ARG_pp)->objbind_table, MY_dummy, MY_value) {\ -NAME_ob = MY_value; +#define property_page_objprop_iterate(ARG_pp, NAME_op)\ + hash_values_iterate((ARG_pp)->objprop_table, NAME_op) +#define property_page_objprop_iterate_end hash_values_iterate_end -#define property_page_objbind_iterate_end \ - } hash_iterate_end;\ -} while (0) +#define property_page_objbind_iterate(ARG_pp, NAME_ob)\ + hash_values_iterate((ARG_pp)->objbind_table, NAME_ob) +#define property_page_objbind_iterate_end hash_values_iterate_end / diff --git a/server/edithand.c b/server/edithand.c index 04ca03e..64dff4a 100644 --- a/server/edithand.c +++ b/server/edithand.c @@ -98,9 +98,9 @@ static void check_edited_tile_terrains(void) return; } - hash_iterate(unfixed_tile_table, ptile, dummy) { + hash_keys_iterate(unfixed_tile_table, ptile) { fix_tile_on_terrain_change(ptile, FALSE); - } hash_iterate_end; + } hash_keys_iterate_end; hash_delete_all_entries(unfixed_tile_table); assign_continent_numbers(); diff --git a/utility/hash.c b/utility/hash.c index e212b2d..a581b91 100644 --- a/utility/hash.c +++ b/utility/hash.c @@ -133,6 +133,13 @@ struct hash_table { bool no_shrink; /* do not auto-shrink when set */ }; +struct hash_iter { + struct iterator vtable; + const struct hash_bucket *b, *end; +}; + +#define HASH_ITER(p) ((struct hash_iter *)(p)) + /* Calculate hash value given hash_table ptr and key: */ #define HASH_VAL(h,k) (((h)->fval)((k), ((h)->num_buckets))) @@ -785,82 +792,110 @@ const void *hash_value_by_number(const struct hash_table *h, } /** - If the hash table is not empty, sets 'iter' to point to the start of the - hash table and returns TRUE. Otherwise returns FALSE. + Prevent or allow the hash table automatically shrinking.
[Freeciv-Dev] (PR#17435) island generator connects continents
http://bugs.freeciv.org/Ticket/Display.html?id=17435 > > [book - Thu Dec 11 23:56:50 2008]: > > I have confirmed that the island generator (gen 3) will > sometimes place islands in a way that there is no ocean > between them. I have also tested the patch and it solved > the problem in all my tests. Since the code looks fine I > will commit it soon (if no objections are raised). And here is the trunk version of the patch. --- 俺は代数をもっと学びたい。 diff --git a/server/generator/mapgen.c b/server/generator/mapgen.c index 3756a65..402df67 100644 --- a/server/generator/mapgen.c +++ b/server/generator/mapgen.c @@ -1613,9 +1613,7 @@ static bool is_near_land(struct tile *ptile) { /* Note this function may sometimes be called on land tiles. */ adjc_iterate(ptile, tile1) { -const struct terrain *pterrain1 = tile_terrain(tile1); -if (T_UNKNOWN != pterrain1 -&& !terrain_has_flag(pterrain1, TER_OCEANIC)) { +if (!is_ocean(tile_terrain(tile1))) { return TRUE; } } adjc_iterate_end; ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#15947) 2.1 - Island generator doesn't generate any rivers
http://bugs.freeciv.org/Ticket/Display.html?id=15947 > > [bjo...@gmail.com - Wed Oct 11 08:30:52 2006]: > > So I fixed fill_island_rivers(..) as best I could with my > rusty programming skills. I tested your patch and it works well. In the attached patches I made some minor formatting and style improvements, and made a version of the patch for trunk. There are some places that look a little weird to me, or I just cannot figure out what they are supposed to do, though this is mostly in the code prior to your changes: - What is the point of the variable 'k'? And what exactly does the 'i == k' test mean? - Why do you multiply failsafe by 5? - What is the point of 'myrand(100) < coast', since 'coast' is always equal to 1 hence the expression only ever has a 1% chance of being true. These all have pretty minor consequences, so if nobody knows the answers I guess I'll just leave the code as is. > River mouths can now only be surrounded by 2 ocean tiles, > only 1 of which is cardinal. This gets rid of the hideous > corner / peninsular 2 or 3 mouthed river outlets. Makes it > look more natural too, especially when they start from an > inlet or landlocked lake. Also ensures ~90% of the time > there are 2 directions the river can go from the mouth, > pushing the river further inland and usually making it > more than 1 tile long. I like the way rivers end up looking with these conditions. > Increased the amount of river tiles generated by 75% > for the island generator. I figure rivers will be more > important now the capital gets corruption and a 75% > production bonus under despotism. High production tiles > that still produce trade are best in this situation. > Also in gen1 most inland tiles are mountains / hills, > it's a lot harder to irrigate inland gen3 islands with > random terrain placement. I really wish rivers were still > a pregame option instead of having to turn the world into > swamp and jungle. I'm not sure that adding a hard-coded 75% increase is the best solution. Anyway it is fine for now; it would not be hard at all to implement a 'rivers' setting that controls the amount of rivers the generator places. I'll submit this in another ticket after this one. > Increased the rivers aversion to ocean, and reduced its > windiness and tendency to fork. This makes it go further > inland and windy forking rivers ain't as useful for unit > movement / irrigation. Ok. > Changed all the cardinal / percent - TRUE's & FALSE's into > constants so the code is more readable. Just picked the > m_ prefix out of thin air for map.h . Should I of used > #DEFINES or just commented every line like the generator1 > river function instead ?. The static const values are fine I suppose, though I renamed them to have a "C_" prefix (for "count", since they affect the terrain counting function) and to use all uppercase. Possibly these could be turned into enum flag values and the two boolean arguments to the counting functions reduced to one. > Split some checks into helper functions making the code > more readable. Good. > Doesn't generate proper rivers for the hex2t tileset. > Although that tileset doesn't create proper coastlines > either and uses a different hex layout to isophex so I'll > assume my code isn't at fault. I'm not sure what you mean by proper rivers, since when I tried a hex topology and the hex2t tileset with gen3, rivers were generated alright. Perhaps the bug causing whatever you found wrong before has since been fixed. --- ある日、たまたま川のそばで遊んでいた。 diff --git a/common/map.h b/common/map.h index f6f6a1e..58cbff4 100644 --- a/common/map.h +++ b/common/map.h @@ -77,6 +77,12 @@ enum topo_flag { TF_HEX = 8 }; +/* Parameters for terrain counting functions. */ +static const bool C_ADJACENT = FALSE; +static const bool C_CARDINAL = TRUE; +static const bool C_NUMBER = FALSE; +static const bool C_PERCENT = TRUE; + #define MAP_IS_ISOMETRIC (topo_has_flag(TF_ISO) || topo_has_flag(TF_HEX)) #define CURRENT_TOPOLOGY (map.topology_id) diff --git a/server/generator/mapgen.c b/server/generator/mapgen.c index 51495a1..a3d8396 100644 --- a/server/generator/mapgen.c +++ b/server/generator/mapgen.c @@ -1494,15 +1494,53 @@ static void fill_island(int coast, long int *bucket, } /** - fill an island with rivers + Returns TRUE if ptile is suitable for a river mouth. +**/ +static bool island_river_mouth_suitability(const struct tile *ptile) +{ + int num_card_ocean, pct_adj_ocean, num_adj_river; + + num_card_ocean = count_ocean_near_tile(ptile, C_CARDINAL, C_NUMBER); + pct_adj_ocean = count_ocean_near_tile(ptile, C_ADJACENT, C_PERCENT); + num_adj_river = count_special_near_tile(ptile, C_ADJACENT, C_NUMBER, + S_RIVER); + + return (num_card_
[Freeciv-Dev] (PR#40598) Embassy lost over save/reload
http://bugs.freeciv.org/Ticket/Display.html?id=40598 > > [chrisk - Sun Dec 14 05:58:11 2008]: > > > Trunk Revision 15365 GTK > > All my embassies get lost when I save the game and reload it. > Pretty new. Probably another case of players_iterate vs. player_slots_iterate. I'll check it out. --- 大使館から脱出せよ! ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40600) Bug with civserver.exe
http://bugs.freeciv.org/Ticket/Display.html?id=40600 > > [arch.and...@mail.ru - Sun Dec 14 11:38:50 2008]: > > Good day! > Today I'm upgraded to new version of freeciv (2.1.8) > and server begins disconnecting my client with this message > > 2: Lost connection: Andrey from localhost [...] > 1: cut connection [...] due to huge send buffer (2) > > No other technical information received or displayed on > the screen. I'm not sure how that particular error condition could have been triggered, though it could be due to some changes I made trying to fix other connection related bugs. What system are you running on (e.g. windows, linux, osx, etc.) and what exactly are you doing to cause the error to occur? Are you trying to start a new local game, or connecting to some server on the internet? Also, does the error always occur, or only sometimes? --- 生き返った死体の衝撃だ。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#12825) freeciv doesn't work on small-resolution displays
http://bugs.freeciv.org/Ticket/Display.html?id=12825 > > [guest - Mon Dec 15 08:24:56 2008]: > > > [book - Mo 10. Nov 2008, 01:16:10]: > > > > > [guest - Sun Nov 09 12:02:10 2008]: > > > > > > This is still an issue. A lot of netbooks have a 1024x600 > > > resolution on which freeciv is unplayable. Please consider > > > making the interface work on those screens. > > > > Could you be more specific about what makes it unplayable, > > for example what client you are using and what parts of the > > interface do not fit correctly. > > I'm not the guest above, but i have the same problem: > > If I want to start a new game there is a dialog where i > can configure my opponents and set game parameters. The > dialog buttons are not reachable with 600 pixels height. > > On the other hand on my Nokia N800 with 800x480 px > resolution there is a good freeciv port... > > Are there special configuration files or parameter i can > use to solfe this issue? No, the basic widget layout is hard-coded in the program. Alright, I will assume that this is a problem with the gtk version, specifically that the way the widgets are packed and/or set to minimum sizes prevents the entire window from being resized down to fit on your display. I'll see about reworking the gui layout code so that resizing is at least possible. In the meantime you could try the sdl gui and play with its video options to see if you can make the game playable on your display. > Btw. how i can create an account for this bug tracker? That's only really useful if you plan on handling bug reports or submitting sizable contributions (and I do not have access to grant you the priveleges anyway). Just use the bug report email address or the guest account listed on bugs.freeciv.org. --- ちょっと。大ハンマーを持ってくる。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40599) Total buy cost display update bug
http://bugs.freeciv.org/Ticket/Display.html?id=40599 > > [chrisk - Sun Dec 14 06:54:21 2008]: > > > Trunk Revision: 15365 GTK > > When selecting a set of cities with items to buy in the > city report, the total buy costs are shown in the bottom > of the report window. > > Now, when I change the production for these cities, the > amount is not updated. Attached patch separates out the label update code and adds a call to it in the required place. --- ブロロロッーブロロ! diff --git a/client/gui-gtk-2.0/cityrep.c b/client/gui-gtk-2.0/cityrep.c index 0970394..f16e0a4 100644 --- a/client/gui-gtk-2.0/cityrep.c +++ b/client/gui-gtk-2.0/cityrep.c @@ -71,6 +71,7 @@ static void city_command_callback(struct gui_dialog *dlg, int response, gpointer data); static void city_selection_changed_callback(GtkTreeSelection *selection); +static void update_total_buy_cost(void); static void create_select_menu(GtkWidget *item); static void create_change_menu(GtkWidget *item); @@ -1207,8 +1208,8 @@ void city_report_dialog_update_city(struct city *pcity) /* update. */ if (found) { update_row(TREE_ITER_PTR(it), pcity); - select_menu_cached = FALSE; + update_total_buy_cost(); } else { city_report_dialog_update(); } @@ -1578,59 +1579,74 @@ static void popup_select_menu(GtkMenuShell *menu, gpointer data) select_menu_cached = TRUE; } -/ -... -*/ -static void city_selection_changed_callback(GtkTreeSelection *selection) +/*** + Update the value displayed by the "total buy cost" label in the city + report, or make it blank if nothing can be bought. +***/ +static void update_total_buy_cost(void) { - int n; + GtkWidget *label, *view; + GList *rows, *p; + GtkTreeModel *model; + GtkTreeSelection *sel; + GtkTreePath *path; + GtkTreeIter iter; + gpointer res; + struct city *pcity; int total = 0; - n = gtk_tree_selection_count_selected_rows(selection); + view = city_view; + label = city_total_buy_cost_label; - if (n == 0) { -gtk_widget_set_sensitive(city_production_command, FALSE); -gtk_widget_set_sensitive(city_center_command, FALSE); -gtk_widget_set_sensitive(city_popup_command, FALSE); -gtk_widget_set_sensitive(city_buy_command, FALSE); - } else { -GList *rows, *p; -GtkTreeModel *model; -GtkTreePath *path; -GtkTreeIter iter; -gpointer res; -struct city *pcity; + if (!view || !label) { +return; + } -gtk_widget_set_sensitive(city_production_command, - can_client_issue_orders()); -gtk_widget_set_sensitive(city_center_command, TRUE); -gtk_widget_set_sensitive(city_popup_command, TRUE); -gtk_widget_set_sensitive(city_buy_command, can_client_issue_orders()); - -rows = gtk_tree_selection_get_selected_rows(selection, &model); -for (p = rows; p != NULL; p = p->next) { - path = p->data; - if (gtk_tree_model_get_iter(model, &iter, path)) { -gtk_tree_model_get(model, &iter, 0, &res, -1); -pcity = res; -if (pcity != NULL) { - total += city_production_buy_gold_cost(pcity); -} + sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(view)); + rows = gtk_tree_selection_get_selected_rows(sel, &model); + + for (p = rows; p != NULL; p = p->next) { +path = p->data; +if (gtk_tree_model_get_iter(model, &iter, path)) { + gtk_tree_model_get(model, &iter, 0, &res, -1); + pcity = res; + if (pcity != NULL) { +total += city_production_buy_gold_cost(pcity); } - gtk_tree_path_free(path); } -g_list_free(rows); +gtk_tree_path_free(path); } + g_list_free(rows); if (total > 0) { -char buf[64]; +char buf[128]; my_snprintf(buf, sizeof(buf), _("Total Buy Cost: %d"), total); -gtk_label_set_text(GTK_LABEL(city_total_buy_cost_label), buf); +gtk_label_set_text(GTK_LABEL(label), buf); } else { -gtk_label_set_text(GTK_LABEL(city_total_buy_cost_label), NULL); +gtk_label_set_text(GTK_LABEL(label), NULL); } } +/*** + Update city report button sensitivity and total buy cost label when the + user makes a change in the selection of cities. +***/ +static void city_selection_changed_callback(GtkTreeSelection *selection) +{ + int n; + + n = gtk_tree_selection_count_selected_rows(selection); + + gtk_widget_set_sensitive(city_production_command, + n > 0 && can_client_issue_orders()); + gtk_widget_set_sensitive(city_center_command, n > 0); + gtk_w
[Freeciv-Dev] (PR#40598) Embassy lost over save/reload
http://bugs.freeciv.org/Ticket/Display.html?id=40598 > > [book - Sun Dec 14 06:25:45 2008]: > > > [chrisk - Sun Dec 14 05:58:11 2008]: > > > > > > Trunk Revision 15365 GTK > > > > All my embassies get lost when I save the game and reload it. > > Pretty new. > > Probably another case of players_iterate vs. player_slots_iterate. > I'll check it out. The attached patch should fix the problem. --- ロビーにハムスターがいるんだ。 diff --git a/server/savegame.c b/server/savegame.c index 16256a0..1fe662b 100644 --- a/server/savegame.c +++ b/server/savegame.c @@ -2060,23 +2060,22 @@ static void player_load_main(struct player *plr, int plrno, BV_CLR_ALL(plr->embassy); if (has_capability("embassies", savefile_options)) { -players_iterate(pother) { - if (secfile_lookup_bool(file, "player%d.embassy%d", - plrno, player_number(pother))) { +player_slots_iterate(pother) { + if (secfile_lookup_bool_default(file, FALSE, "player%d.embassy%d", + plrno, player_index(pother))) { BV_SET(plr->embassy, player_index(pother)); } -} players_iterate_end; +} player_slots_iterate_end; } else { /* Required for 2.0 and earlier savegames. Remove eventually and make * the cap check mandatory. */ int embassy = secfile_lookup_int(file, "player%d.embassy", plrno); -players_iterate(pother) { +player_slots_iterate(pother) { if (embassy & (1 << player_index(pother))) { BV_SET(plr->embassy, player_index(pother)); } -} players_iterate_end; - +} player_slots_iterate_end; } p = secfile_lookup_str_default(file, NULL, "player%d.city_style_by_name", ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40594) Bug: blank (Research) tab causes crash
http://bugs.freeciv.org/Ticket/Display.html?id=40594 > > [jesdisci...@gmail.com - Wed Dec 10 05:04:53 2008]: > > I was fairly late in a game yesterday and had noticed > that the game slowed as its state got more complex. > During the AI's turn, the window would gray to indicate > such, and changes with large ramifications (mainly changing > governors) took a long time to process. I was in the > Cities report, changing the governors of several cities; > when I was done, I noticed a tab handle with no label or X. > I clicked it to see what it was, and the game crashed. > I restarted Freeciv and found my game safely tucked away > in an autosave (whew!); I didn't experience any symptoms > of the crash. > > I saw a blank tab handle again today, once again late in > the game and preceded by the same symptoms. Except this > time I was already in the tab; it was the Research report. > I clicked where the X should have been and nothing > happened. I saved my game and changed to View, then back > to Research. The game crashed, so I started Freeciv up > again and found my save. But this time, I experienced > another bug; I'll send it after this one and name it "Bug: > crash causes loss of automatic movement deference". > > Update: I experienced this again in 2.1.8. This time, I > switched to View and back to the offending tab (Diplomacy) > and didn't experience a crash - although the problem wasn't > fixed and the operation slowed the game. Doing the same > thing later caused a crash. I've attached a screenshot of > the original situation. First of all, the AI's "turn" actually happens when the server is doing all of the turn update calculations. Normally you should not be able to do anything during this time (at least, I assume that is the case). I am guessing because the server was in the middle of sending you updated state information when you used the various dialogs, the inconsistent state confused and crashed your client. So until the exact cause of the crash can be located (e.g. with a backtrace) I would suggest not using the game dialogs "between" turns (wait until the turn counter/year advances and civserver stops using all the CPU cycles). --- プランク時間より短い時間を計測してはだめだよ。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#16243) Freeciv 2.1.0-beta1: trade routes
http://bugs.freeciv.org/Ticket/Display.html?id=16243 > > [guest - Mon Sep 04 13:56:42 2006]: > > A small comment concerning this pop-up window. It would be > nice if it has a frame. Being of the same color as the main > dialog, it creates the data overlap effect when activated. Attached patch adds a frame around the label in the popup. --- 俺は濡れ衣を着せられたんだ! diff --git a/client/gui-gtk-2.0/citydlg.c b/client/gui-gtk-2.0/citydlg.c index 94fab4c..c31d8a3 100644 --- a/client/gui-gtk-2.0/citydlg.c +++ b/client/gui-gtk-2.0/citydlg.c @@ -513,7 +513,7 @@ static gboolean show_info_popup(GtkWidget *w, GdkEventButton *ev, struct city_dialog *pdialog = g_object_get_data(G_OBJECT(w), "pdialog"); if (ev->button == 1) { -GtkWidget *p, *label; +GtkWidget *p, *label, *frame; char buf[1024]; switch (GPOINTER_TO_UINT(data)) { @@ -547,12 +547,16 @@ static gboolean show_info_popup(GtkWidget *w, GdkEventButton *ev, p = gtk_window_new(GTK_WINDOW_POPUP); gtk_widget_set_name(p, "Freeciv"); -gtk_container_set_border_width(GTK_CONTAINER(p), 4); +gtk_container_set_border_width(GTK_CONTAINER(p), 2); gtk_window_set_position(GTK_WINDOW(p), GTK_WIN_POS_MOUSE); +frame = gtk_frame_new(NULL); +gtk_container_add(GTK_CONTAINER(p), frame); + label = gtk_label_new(buf); gtk_widget_set_name(label, "city_info_label"); -gtk_container_add(GTK_CONTAINER(p), label); +gtk_misc_set_padding(GTK_MISC(label), 4, 4); +gtk_container_add(GTK_CONTAINER(frame), label); gtk_widget_show_all(p); gdk_pointer_grab(p->window, TRUE, GDK_BUTTON_RELEASE_MASK, ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40601) bad char in city name crashes GTK civclient 2.1.7 and 2.1.8
http://bugs.freeciv.org/Ticket/Display.html?id=40601 > > [bvanev...@gmail.com - Mon Dec 15 02:25:20 2008]: > > In civclient 2.1.7, a random city name was generated, "Perpiny[X]". > The [X] stands for some weird graphic of a presumably unprintable > character. Clicking on this city crashes both civclient 2.1.7 and > 2.1.8 on Windows Vista SP1. I've attached a saved game file, > "garbagechar," that reproduces the problem. Somehow or another, the city name in the save file got turned into the invalid utf8 sequence "Perpiny". When this game is loaded there are numerous gtk error messages about invalid utf8 and the widgets that are supposed to display the city name are blank. Now I looked in the catalan ruleset file where this city name is defined and there it is correctly "Perpiny". I also tried starting a new game (in trunk though) and making Catalan cities with the editor until Perpinya was created, then saving, quitting, and reloading the game. The save file contained the valid utf-8 and the loaded game had the right name. Then I checked the saving and loading code, and as far as I can see it should work regardless of the encoding (so it does not seem likely it chopped off the last byte or something like that). So my best guess is that somehow the contents of the save file got munged into the present state (invalid utf8) outside of freeciv. Are you sure you did not open and re-save it in an editor or something like that? --- 明らかに点突然変異のです。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40601) bad char in city name crashes GTK civclient 2.1.7 and 2.1.8
http://bugs.freeciv.org/Ticket/Display.html?id=40601 > > [bvanev...@gmail.com - Wed Dec 17 03:17:43 2008]: > > On Tue, Dec 16, 2008 at 8:25 PM, Madeline Book > wrote: > > > > So my best guess is that somehow the contents of the save file > > got munged into the present state (invalid utf8) outside of > > freeciv. Are you sure you did not open and re-save it in an > > editor or something like that? > > I did not. Any munging was accomplished by Freeciv. Could be as > simple as a string pointer error somewhere, given that the bizarre > character is at the end of the string. Yes unfortunately that the particular character is at the end of the string does not help to narrow down the cause. By the way, do you play with the "prompt for city names" local option enabled? And if so, does it still make the bad city name if you turn it off? Also, what happens when you play a nation like Brazillian or Turk? Do the utf8 characters in the start or middle of the city names get corrupted too? How about if you edit the save game manually and put in the missing (that's the character with value 0xa0, or 160 in decimal). What happens if you load the game now? Or what if you just paste in "Perpinyà" into the city name suggestion popup or when renaming the city, what does that do (hopefully not just rejected by the server)? Finally, if you were to play as the Catalan nation using the sdl gui and build cities until you get "Perpinyà" suggested, would the name get garbled? I would run these test myself, but on linux they all pass. :( > I don't know if it's related, but Freeciv GTK consistently > fails on Vista after the game has been going a long time. > The GUI windows change colors and become illegible like > they're being bitblitted incorrectly, then civclient > freezes. Maybe GDI objects are being leaked and running out, as was once suggested in a forum posting regarding the freeland tileset. :) > For this reason I always play with "set saveturns 1". > After such a failure, I can always load the most recent > autosaved game. I haven't submitted the bug because I > don't have a deterministic reproducer for it. I just > know that it will happen after several hours of play. > I guess my point is, Freeciv can munge things. Well, on windows we have the added joy of dealing with problems caused by incompatibilities or deficiencies in the gtk libraries used to build the executables. So in cases like this it is possible that the origin of the bug lies in vista "features" or the win32 gtk code (as much as I would prefer it to be in freeciv, since then I could actually fix it). --- これらの文字は繁殖しているかも。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40600) Bug with civserver.exe
http://bugs.freeciv.org/Ticket/Display.html?id=40600 > > [arch.and...@mail.ru - Wed Dec 17 15:51:23 2008]: > > http://bugs.freeciv.org/Ticket/Display.html?id=40600 > > > > >> [arch.and...@mail.ru - Sun Dec 14 11:38:50 2008]: > >> > >> Good day! > >> Today I'm upgraded to new version of freeciv (2.1.8) > >> and server begins disconnecting my client with this message > >> > >> 2: Lost connection: Andrey from localhost [...] > >> 1: cut connection [...] due to huge send buffer (2) > >> > >> No other technical information received or displayed on > >> the screen. > >> > > > > I'm not sure how that particular error condition could have > > been triggered, though it could be due to some changes I made > > trying to fix other connection related bugs. > > > > What system are you running on (e.g. windows, linux, osx, etc.) > > and what exactly are you doing to cause the error to occur? > > Are you trying to start a new local game, or connecting to > > some server on the internet? Also, does the error always occur, > > or only sometimes? > > > This error was returned on server console in process of > current turn (after pressing end turn button in the client > application but before turn calculation complete). Server > stay work but client should be reconnected. I'm running > local server and client applications under Windows XP sp2. > > I'll make some tests like downgrade to lower version but > error does not disappear. In the next test I'm set network > parameters "connection block" and "max seconds for network > buffer to drain" to higher values and it's help, error > doesn't currently present. But I think if count of cities > and units in the game increased this error can return. > > If it's need I can send save file. Now total count of > cities in the game world near 1000 and total count of units > near 6000. World size 30k tiles. Turn calculating time > near 4 minutes. I have good hardware (Core2Quad Q6600, > and 4Gb RAM) this should be enough for gaming in big maps. Thank you for the detailed information, I think I know what is going on. Unfortunately it is a known design bug that the current freeciv network code behaves badly in extreme circumstances (long latency and large data sends), and there is no easy way to fix this without a substantial redesign and rewrite. In your case I think the server tries to send a very large amount of data at once using buffering and this causes the buffer to exceed its maximum capacity. This is probably unavoidable on very large maps with many cities and units. This could be temporarily fixed by increasing the maximum buffer size from 524288 bytes to say 4 MB, but this limit is hard-coded in the program and would require a recompile to change. Anyway here is a patch that increases the limit for freeciv 2.1.8; I will think about making this configurable without recompiling, or perhaps how to redesign the network code without too much grief. --- そんな大きいもの、入るわけないよ! diff --git a/common/connection.c b/common/connection.c index 48fc429..ad7bb17 100644 --- a/common/connection.c +++ b/common/connection.c @@ -136,7 +136,7 @@ static bool buffer_ensure_free_extra_space(struct socket_packet_buffer *buf, buf->nsize = buf->ndata + extra_space; /* added this check so we don't gobble up too much mem */ -if (buf->nsize > MAX_LEN_BUFFER) { +if (buf->nsize > 4 * 1024 * 1024) { return FALSE; } buf->data = (unsigned char *) fc_realloc(buf->data, buf->nsize); ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40601) bad char in city name crashes GTK civclient 2.1.7 and 2.1.8
http://bugs.freeciv.org/Ticket/Display.html?id=40601 > > [bvanev...@gmail.com - Wed Dec 17 21:30:18 2008]: > > On Wed, Dec 17, 2008 at 4:28 PM, Jordi Negrevernis i Font > wrote: > > > > http://bugs.freeciv.org/Ticket/Display.html?id=40601 > > > > > > > I must say that this only happens on Windows GTK2 client... > > not on gtk2 linux client... > > So it's probably an #ifdef in a name generation string handler. Ring > any bells anyone? The name generation does not work that way. The server reads the city name suggestions from the nation ruleset file on startup and sends city name suggestions to the client in PACKET_CITY_NAME_SUGGESTION_INFO. The received name is passed on to gtk code that puts it into the entry box. The only assumptions this code makes is that the string is NULL terminated and less than 32 bytes in length, which is the case with "Perpinyà" (even garbled) from what I can tell from the savefile. What I suspect is that when the string is placed into the entry box, gtk tries to convert it to an encoding other than utf-8, or chops off the last character resulting in the invalid utf-8. This could be proven if you turn off the "prompt for city name" option and build a city with the Perpinya settler. If the name is not garbled and the program does not crash then we would know it is a problem with the string being put into the entry, and hence a bug in the particular gtk libraries used by the freeciv exe on windows. You could also try inputting other valid utf-8 (e.g. my sig) into the name suggestion box, the city rename popup, or just the chat input line to see what it does. On linux these all work fine, so they should too on windows. --- 私のためにいい家を見つけてください。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
Re: [Freeciv-Dev] function genlist_size() causes game to crash after I've added new effect
On 12/17/08, Yoav Luft wrote: > Hi, > I've written a little patch to the stable tree, as a way to acquaint > myself with the code of freeciv. > The patch adds the new functionality of plagues to game, which are > determined randomly based on the size, pollution, improvements and > trade routes of a city. > The patch segfaults on me. I get that massage: > Program received signal SIGSEGV, Segmentation fault. > 0x0041bd7d in pay_for_units (pplayer=0x861e18, pcity=0x1890fc0) > at ../utility/speclist.h:110 > 110 return genlist_size(tthis->list); > > it only happens when the game.info.plague_on is true, but I do not > understand what genlist_size() does, or where and why it is called. It > is my first attempt at adding code to freeciv, and I've spent some > nights trying to understand what went wrong, but I'm kinda clueless. > I guess it's not a bug, but rather a I didn't do something they it > should be done, but I could find what that is. > > Attached is the patch. > I will appreciate any help, even in explaining me what genlist_size does. The function genlist_size returns the size of a "genlist" which is a linked list of pointers. Genlists are used to implement speclists, which are just macro-generated interfaces to the genlist functions for specific data types (to avoid the type unsafe void pointers used by genlists). These data structures are defined in utility/genlist.h and utility/speclist.h. The particular segfault you have there is in all likelyhood caused by an operation on a NULL list somewhere; it would help if you looked at the entire backtrace to see the history of function calls. Then when you have a rough idea of where the NULL list might be, you can use gdb to step through the code or just insert some printfs (:D) to have the program tell you how far it gets before crashing. Once you pin point the location of the NULL access you can trace back the code path and find what caused the list to be NULL in the first place (you would check all the changes you made that get activated by your new setting). There is some information about using gdb for debugging here: http://freeciv.wikia.com/wiki/Bug_Reporting Also, I looked at your patch and it is actually not that bad at first glance. Granted you need to setup diff to ignore all those useless files that change every configure/make cycle, and setup your editor to follow the freeciv coding style more closely. Of course this is only if you intend to submit your patch for inclusion later. Here are some more helpful pages: http://freeciv.wikia.com/wiki/How_to_Contribute http://freeciv.wikia.com/wiki/Coding_Style Oh and by the way, you should implement new features on the trunk branch; the "stable" 2.1.x series is only getting bugfixes now. --- 黒死病で死にたくない。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40601) bad char in city name crashes GTK civclient 2.1.7 and 2.1.8
http://bugs.freeciv.org/Ticket/Display.html?id=40601 > > [bvanev...@gmail.com - Wed Dec 17 23:43:51 2008]: > > On Wed, Dec 17, 2008 at 5:42 PM, Madeline Book > wrote: > > > > This could be proven if you turn off the "prompt for city > > name" option and build a city with the Perpinya settler. > > If the name is not garbled and the program does not > > crash then we would know it is a problem with the string > > being put into the entry, and hence a bug in the particular > > gtk libraries used by the freeciv exe on windows. > > I turned off "prompt for city name." When building the settler, the > game now simply crashes. So, the string is being corrupted before it > is delivered to the dialog box. > > > You could also try inputting other valid utf-8 (e.g. my > > sig) into the name suggestion box, the city rename popup, > > or just the chat input line to see what it does. On linux > > these all work fine, so they should too on windows. > > > > > > 私のためにいい家を見つけてください。 > > Your .sig is truncated for length, but it inputs just fine. This is very good, both results imply that gtk is not to blame and that the corruption may be occurring when the city name is being transferred from the client to the server. When you start a client from a dos window, it should print a line like: Encodings: Data=UTF-8, Local=UTF-8, Internal=UTF-8 Does yours match the one above, or is it different? Also, are you using any kind of special character set on your system (e.g. iso_8859-1 or something similar)? --- 我々は隠れ家まであれらの文字をたどった。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40601) bad char in city name crashes GTK civclient 2.1.7 and 2.1.8
http://bugs.freeciv.org/Ticket/Display.html?id=40601 > > [cproc - Thu Dec 18 04:42:10 2008]: > > The default Windows character set in western countries is CP1252: > > http://en.wikipedia.org/wiki/CP1252 Ah thanks for that, the last piece of the puzzle. ;) > In this character set 0xA0 means "non-breakable" space, so this > character gets stripped by remove_trailing_spaces() when reading > the nation file. Indeed, if I start the client with a different local encoding e.g. $ LANG=de_DE ./civ then the trailling "space" eating behavior occurs. This suggests that it might be enough to just start the client in a locale encoded with utf8: C:\> set LANG=en_US.UTF-8 C:\> civclient.exe (Of course this should be done in the directory where the program resides instead of C:.) But the behavior of remove_trailing_spaces() is troubling. Would it be safe to just have it remove only ' ', '\t', '\r', '\v' and '\n', instead of anything for which isspace returns TRUE? Or would this then cause other problems when other kinds of "whitespace" characters are used in the user's locale? Perhaps the server should just set its own (local) encoding to utf8 when it reads the ruleset files, then set it back to what it was originally... :? --- 宇宙の向こうから来て、空間そのものを食ってしまっていた。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40601) bad char in city name crashes GTK civclient 2.1.7 and 2.1.8
http://bugs.freeciv.org/Ticket/Display.html?id=40601 > > [bvanev...@gmail.com - Thu Dec 18 04:26:29 2008]: > > On Wed, Dec 17, 2008 at 9:04 PM, Madeline Book > wrote: > > > > When you start a client from a dos window, it should print > > a line like: > > > > Encodings: Data=UTF-8, Local=UTF-8, Internal=UTF-8 > > > > Does yours match the one above, or is it different? > > Nothing at all is printed on Vista. civclient --help also prints > nothing. In fact, it doesn't matter what command line options I give, > nothing is printed. Documentation on client command line options > appears to be quite out of date. How recently have you done this with > a dos box on Windows? What version of Windows? Sorry, this was my mistake. That line is only printed if the client was configured with debugging support enabled, which I realize is probably not true for the windows packages. --- 腹が減っているんだろうね。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40604) [Patch] Fix load command file name searching
http://bugs.freeciv.org/Ticket/Display.html?id=40604 > Attached patch cleans up the file path and extenstion checking code in the load_command() function. Also, the extensions ".gz", ".bz2", and ".sav.bz2", are added to the searching code since it is a common enough occurrence that save files end up with these extensions. --- どんなに圧縮しても、俺はあなたを見つけます。 diff --git a/server/stdinhand.c b/server/stdinhand.c index 018f511..af02e70 100644 --- a/server/stdinhand.c +++ b/server/stdinhand.c @@ -3386,28 +3386,33 @@ bool load_command(struct connection *caller, const char *filename, bool check) filename); return FALSE; } + { /* it is a normal savegame or maybe a scenario */ -char tmp[MAX_LEN_PATH]; - -my_snprintf(tmp, sizeof(tmp), "%s.sav", filename); -if (!datafilename(tmp)) { - my_snprintf(tmp, sizeof(tmp), "%s.sav.gz", filename); - if (!datafilename(tmp)) { -my_snprintf(tmp, sizeof(tmp), "scenario/%s.sav", filename); -if (!datafilename(tmp)) { - my_snprintf(tmp, sizeof(tmp), "scenario/%s.sav.gz", filename); - if (is_restricted(caller) && !datafilename(tmp)) { -cmd_reply(CMD_LOAD, caller, C_FAIL, _("Cannot find savegame or " - "scenario with the name \"%s\"."), filename); -return FALSE; - } +char testfile[MAX_LEN_PATH]; +const char *paths[] = { "", "scenario/", NULL }; +const char *exts[] = { + "sav", "gz", "bz2", "sav.gz", "sav.bz2", NULL +}; +const char **path, **ext, *found = NULL; + +for (path = paths; !found && *path; path++) { + for (ext = exts; !found && *ext; ext++) { +my_snprintf(testfile, sizeof(testfile), "%s%s.%s", +*path, filename, *ext); +if ((found = datafilename(testfile))) { + sz_strlcpy(arg, found); } } } -if (datafilename(tmp)) { - sz_strlcpy(arg, datafilename(tmp)); -} else { + +if (is_restricted(caller) && !found) { + cmd_reply(CMD_LOAD, caller, C_FAIL, _("Cannot find savegame or " +"scenario with the name \"%s\"."), filename); + return FALSE; +} + +if (!found) { sz_strlcpy(arg, filename); } } ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40605) timer_list_size() crash
http://bugs.freeciv.org/Ticket/Display.html?id=40605 > > [cazf...@gmail.com - Fri Dec 19 11:08:09 2008]: > > 2.1.8, using fantasy ruleset > > Program terminated with signal 11, Segmentation fault. > [New process 20595] > #0 0x0042a01b in genlist_size () > (gdb) bt full > #0 0x0042a01b in genlist_size () > No locals. > #1 0x004e6e40 in timer_list_size () > No locals. > #2 0x004e6d8d in close_connection () > No locals. > [...] > > This is probably related to the fact that incoming connection was > rejected by auth code. > > > I'm not sure if this is bug in official Freeciv. I have local > modification for prohibiting login with certain accounts, and bug > might be in that modification. I have seen a very similar backtrace in the past; this is probably due to an attempted used of a NULL genlist. The attached patches for S2_1 and trunk add checks for the NULL list and should at least prevent crashing. --- ピンポン! diff --git a/server/sernet.c b/server/sernet.c index 81d6493..b7ab4a5 100644 --- a/server/sernet.c +++ b/server/sernet.c @@ -116,6 +116,9 @@ static int socklan; #define SPECLIST_TAG timer #define SPECLIST_TYPE struct timer #include "speclist.h" +#define timer_list_iterate(ARG_list, NAME_item) \ + TYPED_LIST_ITERATE(struct timer, (ARG_list), NAME_item) +#define timer_list_iterate_end LIST_ITERATE_END #define PROCESSING_TIME_STATISTICS 0 @@ -196,14 +199,18 @@ static void handle_readline_input_callback(char *line) */ void close_connection(struct connection *pconn) { - while (timer_list_size(pconn->server.ping_timers) > 0) { -struct timer *timer = timer_list_get(pconn->server.ping_timers, 0); + if (!pconn) { +return; + } -timer_list_unlink(pconn->server.ping_timers, timer); -free_timer(timer); + if (pconn->server.ping_timers != NULL) { +timer_list_iterate(pconn->server.ping_timers, timer) { + free_timer(timer); +} timer_list_iterate_end; +timer_list_unlink_all(pconn->server.ping_timers); +timer_list_free(pconn->server.ping_timers); +pconn->server.ping_timers = NULL; } - assert(timer_list_size(pconn->server.ping_timers) == 0); - timer_list_free(pconn->server.ping_timers); /* safe to do these even if not in lists: */ conn_list_unlink(game.all_connections, pconn); diff --git a/utility/timing.c b/utility/timing.c index 49337c8..ee2a6a1 100644 --- a/utility/timing.c +++ b/utility/timing.c @@ -213,7 +213,9 @@ struct timer *renew_timer_start(struct timer *t, enum timer_timetype type, ***/ void free_timer(struct timer *t) { - free(t); + if (t != NULL) { +free(t); + } } /** diff --git a/server/sernet.c b/server/sernet.c index 055bff1..7f1a130 100644 --- a/server/sernet.c +++ b/server/sernet.c @@ -118,6 +118,9 @@ static int socklan; #define SPECLIST_TAG timer #define SPECLIST_TYPE struct timer #include "speclist.h" +#define timer_list_iterate(ARG_list, NAME_item) \ + TYPED_LIST_ITERATE(struct timer, (ARG_list), NAME_item) +#define timer_list_iterate_end LIST_ITERATE_END #define PROCESSING_TIME_STATISTICS 0 @@ -198,16 +201,19 @@ static void handle_readline_input_callback(char *line) */ void close_connection(struct connection *pconn) { - cancel_connection_votes(pconn); + if (!pconn) { +return; + } - while (timer_list_size(pconn->server.ping_timers) > 0) { -struct timer *timer = timer_list_get(pconn->server.ping_timers, 0); + cancel_connection_votes(pconn); -timer_list_unlink(pconn->server.ping_timers, timer); -free_timer(timer); + if (pconn->server.ping_timers != NULL) { +timer_list_iterate(pconn->server.ping_timers, timer) { + free_timer(timer); +} timer_list_iterate_end; +timer_list_free(pconn->server.ping_timers); +pconn->server.ping_timers = NULL; } - assert(timer_list_size(pconn->server.ping_timers) == 0); - timer_list_free(pconn->server.ping_timers); /* safe to do these even if not in lists: */ conn_list_unlink(game.all_connections, pconn); diff --git a/utility/timing.c b/utility/timing.c index 31ad317..66ac3d0 100644 --- a/utility/timing.c +++ b/utility/timing.c @@ -213,7 +213,9 @@ struct timer *renew_timer_start(struct timer *t, enum timer_timetype type, ***/ void free_timer(struct timer *t) { - free(t); + if (t != NULL) { +free(t); + } } /** ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40610) auto_arrange_workers: Assertion `cmr.found_a_valid' failed.
http://bugs.freeciv.org/Ticket/Display.html?id=40610 > This was reported on the forums: http://forum.freeciv.org/viewtopic.php?t=5730 Server fails to autoarrange workers triggering the assertion in the subject line. The program version is 2.1.8, a fedora package. Server log also has: 3: Warning: calloc with size 0 at line 576 of cm.c 3: Warning: calloc with size 0 at line 577 of cm.c which indicates that ntypes=0 is passed to the function init_partial_solution(). I assume this was never expected by the author of that function, so the server must have gotten into an inconsistent state some time before that point (missing city workers or wrong city size?). I could just make the cm functions more robust (i.e. better checking of arguments) and turn the assertion in auto_arrange_workers() into an if-statement, but I will investigate some more and hopefully find the real cause of the bug. :( --- クリスマスには石炭の塊だけが欲しい。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
Re: [Freeciv-Dev] 2.1.8 civserver failure
On 12/27/08, Piotr Budny wrote: > After starting the game, I move my pawns, when the turn ends, and starting > new, the server hangs up. > I'm using PLD Linux, 2.1.8 freeciv. > [...] >> civserver: cityturn.c:276: auto_arrange_workers: Assertion > `cmr.found_a_valid' failed. Thanks for the bug report, this has recently been reported by other users and I started a bug tracker ticket at: http://bugs.freeciv.org/Ticket/Display.html?id=40610 Please post any new information to that page (I will copy this message there). I'm starting to suspect that it might be a compiler bug (we've had problems before due to code not working when compiled with gcc 4.x optimizations). What version of gcc are you using, and do you know if the freeciv binary you are using was compiled with -O2 (or more)? If you have some time it would help my debugging too if you could confirm whether the 2.1.8 sources in svn://svn.gna.org/svn/freeciv/branches/S2_1 when compiled with with or without --enable-debug and with or without optimizations (-O0 that's big oh, zero) or with an earlier gcc (e.g. 3.x). --- コンパイラーの中に隠れていて、コードを食べている。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40610) auto_arrange_workers: Assertion `cmr.found_a_valid' failed.
http://bugs.freeciv.org/Ticket/Display.html?id=40610 > Forwarded from a posting to freeciv-dev: On 12/27/08, Piotr Budny wrote: > After starting the game, I move my pawns, when the turn ends, > and starting new, the server hangs up. > I'm using PLD Linux, 2.1.8 freeciv. #0 0xf7fda430 in __kernel_vsyscall () #1 0x4b60e7a7 in *__GI_raise (sig=) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64 #2 0x4b60fed8 in *__GI_abort () at abort.c:88 #3 0x4b6072fa in *__GI___assert_fail (assertion=Could not find the frame base for "*__GI___assert_fail". ) at assert.c:78 #4 0x080724e0 in auto_arrange_workers (pcity=0x84f94b0) at cityturn.c:276 #5 0x0806f238 in create_city (pplayer=0x829e11c, ptile=0x8a40558, name=0x877ebc0 "Timbuktu") at citytools.c:1039 #6 0x080aea6d in city_build (pplayer=0x829e11c, punit=0x8aa41b8, name=0x877ebc0 "Timbuktu") at unithand.c:555 #7 0x080ac216 in auto_settler_findwork (pplayer=0x829e11c, punit=0x8aa41b8, state=0xff8d2530, recursion=1) at settlers.c:94 #8 0x080aba4b in auto_settler_findwork (pplayer=0x829e11c, punit=0x8aa41b8, state=0xff8d2530, recursion=0) at settlers.c:1158 #9 0x080ac7ce in auto_settlers_player (pplayer=0x829e11c) at settlers.c:1296 #10 0x080544c5 in srv_main () at srv_main.c:786 #11 0x0804a735 in main (argc=8, argv=0xff8da5a4) at civserver.c:258 >> civserver: cityturn.c:276: auto_arrange_workers: Assertion > `cmr.found_a_valid' failed. I'm starting to suspect that it might be a compiler bug (we've had problems before due to code not working when compiled with gcc 4.x optimizations). What version of gcc are you using, and do you know if the freeciv binary you are using was compiled with -O2 (or more)? If you have some time it would help my debugging too if you could confirm whether the 2.1.8 sources in svn://svn.gna.org/svn/freeciv/branches/S2_1 when compiled with with or without --enable-debug and with or without optimizations (-O0 that's big oh, zero) or with an earlier gcc (e.g. 3.x). --- ボリボリ食べるな! ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40610) auto_arrange_workers: Assertion `cmr.found_a_valid' failed.
http://bugs.freeciv.org/Ticket/Display.html?id=40610 > > [guest - Sat Dec 27 19:12:10 2008]: > > Compiling with -O0 (before was -O2) like: > ./configure --prefix=/home/users/vip/freeciv --enable-debug > CFLAGS="-O0" and server stopped hanging up while building cities. > So, gcc bug? Yes, it is looking more and more like the same situation we had before, gcc 4.x optimizations break some parts of the code. I'll try to find and "re-phrase" the code that is being miscompiled... --- 百回書き直しなさい。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40611) default.serv sets startunits to cccwwx
http://bugs.freeciv.org/Ticket/Display.html?id=40611 > > [bvanev...@gmail.com - Sat Dec 27 22:33:31 2008]: > > default.serv has a hack in it which sets startunits to "cccwwx". This > does not match the server's hardwired default value when starting a > game of Freeciv from scratch. The hack is supposed to change the > startunits back to "correct values," but at this moment in Freeciv > development history, it's an incorrect value. > > Reproducer: > 1) using any GTK client, select "Start New Game" > 2) /show startunits. The value will be "ccwwx" > 3) using the gui, select Ruleset Version "civ1". startunits will be > changed. > 4) using the gui, select Ruleset Version "default". startunits will > be changed again. > 5) /show startunits. It now has value "cccwwx", one extra settler. > > Solution: change line in default.serv to ccwwx Ok. --- 誰がボケナス。 diff --git a/data/default.serv b/data/default.serv index 59c020d..8ff4916 100644 --- a/data/default.serv +++ b/data/default.serv @@ -8,5 +8,5 @@ rulesetdir default # HACK: These are included to cancel out the settings from civ2.ruleset, etc. set sciencebox 100 -set startunits cccwwx +set startunits ccwwx set borders 4 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40608) Screen doesn't refresh if maximized in 2.1.8 on windows XP
http://bugs.freeciv.org/Ticket/Display.html?id=40608 > > [fin...@gmx.net - Sun Dec 28 21:56:40 2008]: > > (-> the window resizes itself, exeeding the 1024x768 of the screen -> > another bug) I remember from warclient that this automatic resizing was a bug in the win32 gtk libraries on windows. It should be fixed in newer versions (possible the development version, not stable). --- 欲しいだけ大きくなるよ。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#16811) Issue tracking system for Freeciv
http://bugs.freeciv.org/Ticket/Display.html?id=16811 > > [s1kevin - Mon Dec 29 07:06:22 2008]: > > This bug has been open since May of '06. Is anyone taking > my offer to assist moving from RT to Bugzilla seriously? > If not, please close this issue. > > I believe this is the best way I can contribute now to > the development of Freeciv - by providing what I feel > is a far superior issue tracking system with much better > search capabilities and more transparency to help encourage > developer participation (even new developers). If you use > Eclipse as your development environment, it has support > for task management (via Mylyn) directly in Bugzilla. > > I might be willing to assist in Freeciv code development, > but at this point, I'd want to use an issue tracking > system that supports me as both a user and a developer. > From my perspective, RT is not designed for software > development projects. Bugzilla is. Here is what needs to happen: 1. A host for the bug tracker must be found. This is either a machine someone can install/configure bugzilla on, or a service hosting bugzilla. 2. The current RT system needs to be frozen, all new requests redirected to the new tracker, and the public bug report address updated everywhere. 3. Current outstanding tickets and history should be moved to the new tracker. The problem has always been 1, since a dedicated machine (e.g. in a data center) costs money, or a free service is restricted (e.g. in allowed space) or missing some key functionality. Assuming a solution to the above exists, 2 is hard because the only people (person?) with the required access to the RT machine is not an active developer and/or checks freeciv-dev only infrequently (besides probably not having the time to make the changes in RT, if that is even possible). 3 is not crucial; I assume there are less than 100 important open tickets, which can be moved by hand as they are handled, and the RT system could be kept in "read-only" mode to make the history available (in the minimum-effort scenario). If as you said using bugzilla would help encourage developer contributions from the community then I am strongly for it. This project is in great need of help from competent coders to handle bug reports, assist less experienced programmers with their ideas, and fix the design mistakes that have broken past working features (e.g. borders) and are causing new development to stagnate. --- サンタクロースではなく、キッコーマンだよ。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40615) [Editor] Remove border/territory tool
http://bugs.freeciv.org/Ticket/Display.html?id=40615 > I can't see how to logically design a "border editing tool" with the current or any assumed future border system so here is a patch that removes it. If I or someone else thinks of a use for this tool that makes sense, it can of course be easily reinstated. --- この国境は天命である。 client/editor.c | 10 -- client/gui-gtk-2.0/editgui.c |7 --- common/packets.def |6 -- server/edithand.c| 34 -- 4 files changed, 0 insertions(+), 57 deletions(-) diff --git a/client/editor.c b/client/editor.c index d5b89f8..1f6be9e 100644 --- a/client/editor.c +++ b/client/editor.c @@ -177,9 +177,6 @@ void editor_init(void) | ETF_HAS_COPY_PASTE, _("Create city.\nShortcut: c")); tool_init(ETT_VISION, _("Vision"), ETF_HAS_SIZE, _("Modify player's tile knowledge.\nShortcut: v")); - tool_init(ETT_TERRITORY, _("Territory"), -ETF_HAS_SIZE | ETF_HAS_APPLIED_PLAYER, -_("Change tile ownership.\nShortcut: b")); tool_init(ETT_STARTPOS, _("Start Position"), ETF_HAS_APPLIED_PLAYER, _("Place a player start position.\nShortcut: p")); @@ -861,10 +858,6 @@ void editor_apply_tool(const struct tile *ptile, } break; - case ETT_TERRITORY: -dsend_packet_edit_territory(my_conn, x, y, erase ? -1 : apno, size); -break; - case ETT_STARTPOS: dsend_packet_edit_startpos(my_conn, x, y, erase ? -1 : apno); break; @@ -1196,9 +1189,6 @@ struct sprite *editor_tool_get_sprite(enum editor_tool_type ett) case ETT_VISION: return sprites->vision; break; - case ETT_TERRITORY: -return sprites->territory; -break; case ETT_STARTPOS: return sprites->startpos; break; diff --git a/client/gui-gtk-2.0/editgui.c b/client/gui-gtk-2.0/editgui.c index 2168cc2..f9d1b55 100644 --- a/client/gui-gtk-2.0/editgui.c +++ b/client/gui-gtk-2.0/editgui.c @@ -513,7 +513,6 @@ static struct editbar *editbar_create(void) editbar_add_tool_button(eb, ETT_UNIT); editbar_add_tool_button(eb, ETT_CITY); editbar_add_tool_button(eb, ETT_VISION); - editbar_add_tool_button(eb, ETT_TERRITORY); editbar_add_tool_button(eb, ETT_STARTPOS); separator = gtk_vseparator_new(); @@ -1407,9 +1406,6 @@ static GdkPixbuf *get_tool_value_pixbuf(enum editor_tool_type ett, case ETT_VISION: sprite = sprites->vision; break; - case ETT_TERRITORY: -sprite = sprites->territory; -break; case ETT_STARTPOS: sprite = sprites->startpos; break; @@ -1643,9 +1639,6 @@ gboolean handle_edit_key_press(GdkEventKey *ev) case GDK_v: new_ett = ETT_VISION; break; - case GDK_b: -new_ett = ETT_TERRITORY; -break; case GDK_p: new_ett = ETT_STARTPOS; break; diff --git a/common/packets.def b/common/packets.def index 8455fda..300fac4 100644 --- a/common/packets.def +++ b/common/packets.def @@ -1471,12 +1471,6 @@ PACKET_EDIT_TILE_BASE=157;cs,handle-per-conn,dsend UINT8 size; end -PACKET_EDIT_TERRITORY=158;cs,handle-per-conn,dsend - COORD x, y; key - PLAYER owner; # -1 (or other out of range) for erasing - UINT8 size; -end - PACKET_EDIT_STARTPOS=159;cs,handle-per-conn,dsend COORD x, y; key NATION nation; # -1 for erase diff --git a/server/edithand.c b/server/edithand.c index 3656184..46f0612 100644 --- a/server/edithand.c +++ b/server/edithand.c @@ -1194,40 +1194,6 @@ void handle_edit_toggle_fogofwar(struct connection *pc, int plr_no) } / - Change the "ownership" of the tile(s) at the given coordinates. -/ -void handle_edit_territory(struct connection *pc, int x, int y, int owner, - int size) -{ - struct player *pplayer; - struct tile *ptile_center; - - ptile_center = map_pos_to_tile(x, y); - if (!ptile_center) { -notify_conn(pc->self, NULL, E_BAD_COMMAND, -_("Cannot edit territory of tile (%d, %d) because " - "it is not on the map!"), x, y); -return; - } - - /* NULL is ok; represents "no owner". */ - pplayer = player_by_number(owner); - - conn_list_do_buffer(game.est_connections); - square_iterate(ptile_center, size - 1, ptile) { -if (tile_owner(ptile) == pplayer -|| tile_city(ptile) != NULL) { - continue; -} -/* FIXME: This does not play well with border code - * once edit mode is exited. */ -tile_set_owner(ptile, pplayer); -send_tile_info(NULL, ptile, FALSE); - } square_iterate_end; - conn_list_do_unbuffer(game.est_connections); -} - -/ Set the given position to be the start position for the given nation. *
[Freeciv-Dev] (PR#40605) timer_list_size() crash
http://bugs.freeciv.org/Ticket/Display.html?id=40605 > > [book - Sat Dec 20 04:05:05 2008]: > > > [cazf...@gmail.com - Fri Dec 19 11:08:09 2008]: > > > > 2.1.8, using fantasy ruleset > > > > Program terminated with signal 11, Segmentation fault. > > [New process 20595] > > #0 0x0042a01b in genlist_size () > > (gdb) bt full > > #0 0x0042a01b in genlist_size () > > No locals. > > #1 0x004e6e40 in timer_list_size () > > No locals. > > #2 0x004e6d8d in close_connection () > > No locals. > > [...] > > > > This is probably related to the fact that incoming connection was > > rejected by auth code. > > > > > > I'm not sure if this is bug in official Freeciv. I have local > > modification for prohibiting login with certain accounts, and bug > > might be in that modification. > > I have seen a very similar backtrace in the past; this > is probably due to an attempted used of a NULL genlist. > The attached patches for S2_1 and trunk add checks for > the NULL list and should at least prevent crashing. I committed the patches; if you find any more clues as to the original cause of the bug or you still experience problems, feel free to re-open the ticket. --- 正確な時計が必要なのです。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40612) Patch: migration
http://bugs.freeciv.org/Ticket/Display.html?id=40612 > > [matthias.pfaffer...@mapfa.de - Tue Dec 30 21:34:34 2008]: > > here is an updated version of the patch. Unfortunately I just made adjustements to you previous patch today, and was about to post the updated version when I noticed you already did. :( Anyway, please at least read over the code in the file migrate_v3.patch and make sure your patch follows the same style. Maybe integrate some of the ideas in it, such as a setting to control the number of turns between migrations (perhaps better than the hard-coded 5). In particular: - No lines longer than 76 characters + 1 newline. - Multi-line function arguments lined up to column one past the initial '(' and similarly for if-statements. - Use city_tile(pcity) instead of pcity->tile, and similar. - Use LOG_DEBUG not LOG_NORMAL for debugging messages. - Use is_capital(pcity) directly instead of find_palace(). - Use const in function arguments if the function does not modify the arguments (e.g. the score function). - Make the default setting values disable migration. I also wonder if there could arise a situation where migration happens from city A to city B, and then back again from city B to city A, because A happened to be before B in the city list. Perhaps the migration score should first be calculated for all possible source and destination cities, then the migrations actually performed? Anyway I'll check it again in at least a few days and when I'm sure you are not working on it too. ;) --- 私の人生は大移住の話から始まります。 common/game.c |1 + common/game.h |4 ++ common/packets.def |1 + server/cityturn.c | 135 server/cityturn.h |3 + server/savegame.c |4 ++ server/settings.c | 13 + server/srv_main.c |7 +++ 8 files changed, 168 insertions(+), 0 deletions(-) diff --git a/common/game.c b/common/game.c index f0d4378..0d5bfab 100644 --- a/common/game.c +++ b/common/game.c @@ -275,6 +275,7 @@ void game_init(void) game.info.celebratesize = GAME_DEFAULT_CELEBRATESIZE; game.info.savepalace= GAME_DEFAULT_SAVEPALACE; game.info.natural_city_names = GAME_DEFAULT_NATURALCITYNAMES; + game.info.migration = GAME_DEFAULT_MIGRATION; game.info.angrycitizen = GAME_DEFAULT_ANGRYCITIZEN; game.info.foodbox = GAME_DEFAULT_FOODBOX; game.info.shieldbox = GAME_DEFAULT_SHIELDBOX; diff --git a/common/game.h b/common/game.h index 4e75ece..f593bf2 100644 --- a/common/game.h +++ b/common/game.h @@ -250,6 +250,10 @@ bool setting_class_is_changeable(enum sset_class class); #define GAME_DEFAULT_NATURALCITYNAMES TRUE +#define GAME_DEFAULT_MIGRATION 0 +#define GAME_MIN_MIGRATION 0 +#define GAME_MAX_MIGRATION 100 + #define GAME_DEFAULT_AQUEDUCTLOSS0 #define GAME_MIN_AQUEDUCTLOSS0 #define GAME_MAX_AQUEDUCTLOSS100 diff --git a/common/packets.def b/common/packets.def index 8455fda..a00a2c4 100644 --- a/common/packets.def +++ b/common/packets.def @@ -414,6 +414,7 @@ PACKET_GAME_INFO=15; sc UINT8 razechance; BOOL savepalace; BOOL natural_city_names; + UINT8 migration; BOOL turnblock; BOOL fixedlength; BOOL auto_ai_toggle; diff --git a/server/cityturn.c b/server/cityturn.c index b860a5e..412eddc 100644 --- a/server/cityturn.c +++ b/server/cityturn.c @@ -1867,3 +1867,138 @@ static bool disband_city(struct city *pcity) remove_city(pcity); return TRUE; } + +/*** + Helper function to find the "migration desirability" of a city. The higher + the score the more likely citizens will migrate to it. + + The score depends on the total trade and shield output of the city, its + size, number of ocean squares around it, and the shield cost of all the + improvements in the city. The score is doubled for the player's capital + city (the one containing the palace small wonder). +***/ +static int city_migration_score(const struct city *pcity) +{ + int score = 0; + + if (!pcity) { +return 0; + } + + score = pcity->prod[O_TRADE] + pcity->prod[O_SHIELD]; + score += 10 * pcity->size; + square_iterate(city_tile(pcity), 2, ptile) { +if (is_ocean(tile_terrain(ptile))) { + score += 2; +} + } square_iterate_end; + + city_built_iterate(pcity, pimprove) { +score += impr_build_shield_cost(pimprove) * 2; + } city_built_iterate_end; + + if (find_palace(city_owner(pcity)) == pcity) { +score *= 2; + } + + return score; +} + +/** + Do the migrations between the cities that overlap. Migrants go to the + city with higher city_migration_score(), if the growth of the target + city is not blocked due to a missing improvement. + + The setting
[Freeciv-Dev] (PR#40616) patch: allow 2.1.8 to compile under sun studio community edition 11/08
http://bugs.freeciv.org/Ticket/Display.html?id=40616 > > [james.mccl...@gmail.com - Wed Dec 31 01:55:26 2008]: > > This email contains a patch that allows version 2.1.8 of > FreeCiv to compile under the 11/08 version (the latest > I believe) version of the Sun Studio Community Edition > compiler. The patch seems to produce working executables > on the AMD64 version of OpenSUSE 11.1 with the compiler > mentioned above. The changes are all minor ones which > have to do with differences in implementation of the C99 > standard between the Sun Studio compiler and gcc. I don't understand the purpose of the changes in your patch; what are the errors returned by the compiler for the existing code? And where can I find a c99 implementation status page for the "sun studio compiler" (for example, like the gcc one: http://gcc.gnu.org/c99status.html)? The main c99 feature in use in the freeciv code is variable length arrays (i.e. arrays allocated on the stack); most other c99 uses can be rephrased to equivalent c expressions, I would hope. Also I don't agree with the way your patch changes the code. If anything the #if should be on the compiler version, and not "#if 0" or "#if 1". The way upkeep_ptr is used is very unattractive. Why does it have to be a global variable, why not just declare it in the scope of the function? Why does it have to be a pointer anyway? Is it the 'struct repoinfo' definition within the function activeunits_report_dialog_update() that is causing the compiler to choke? Why not just move it out then? Since there are plently of uses of struct foo { int array[A_CONSTANT]; }; elsewhere in the code. Maybe it is the type of 'O_COUNT' that is messing it up? So make it a macro or just use O_LAST. (Where do you even get 0x20 from?) I find it hard to believe that your compiler would accept > upkeep_ptr = &(unitarray[unit_type(punit)->index].upkeep); > *(upkeep_ptr + o) += punit->upkeep[o]; but not > unitarray[unit_type(punit)->index].upkeep[o] += punit->upkeep[o]; What part of either expression is specific to c99? I would guess that this kind of code occurs in numerous other places as well, yet it only causes compilation problems here? :( > #define COREQ_APPEND(s) \ >(coreq_buf[0] != '\0' \ > - ? cat_snprintf(coreq_buf, sizeof(coreq_buf), Q_("?clistmore:, > %s"), (s)) \ > + ? (void)cat_snprintf(coreq_buf, sizeof(coreq_buf), > Q_("?clistmore:, %s"), (s)) \ > : sz_strlcpy(coreq_buf, (s))) This macro is hideous already, and should at least be made into an inline function. --- 競技に参加するつもりですか? ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40616) patch: allow 2.1.8 to compile under sun studio community edition 11/08
http://bugs.freeciv.org/Ticket/Display.html?id=40616 > Thank you for the explanations and the error message output, that makes the situation somewhat clearer. I still suspect that the problem lies in the definition of 'struct repoinfo'. Can you please try moving it outside the scope of activeunits_report_dialog_update() (i.e. into file scope), and seeing if that fixes the problem? Also, try O_MAX instead of O_COUNT. Failling that, O_COUNT could be defined to a literal numeric constant (i.e. 6), or the 'upkeep' field in repoinfo renamed. Searching for that error message on the web yields a bunch of pages that seem to imply it is due to a bug in the sun compiler. The fact that somehow the compiler gets confused with the "int upkeep;" in 'struct packet_ruleset_building' in common/packets_gen.h would also suggest this. --- 一等賞はとても素敵ですね。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40616) patch: allow 2.1.8 to compile under sun studio community edition 11/08
http://bugs.freeciv.org/Ticket/Display.html?id=40616 > > [james.mccl...@gmail.com - Wed Dec 31 22:12:35 2008]: > > Using O_MAX rather than O_COUNT does work. Moving the definition > out of the function into file scope does not work.. Interesting. So I assume the attached patch completely fixes the compilation problems? --- ですが、全然分かりません。 diff --git a/client/gui-gtk-2.0/repodlgs.c b/client/gui-gtk-2.0/repodlgs.c index 7f40ea1..1272966 100644 --- a/client/gui-gtk-2.0/repodlgs.c +++ b/client/gui-gtk-2.0/repodlgs.c @@ -1178,7 +1178,7 @@ void activeunits_report_dialog_update(void) { struct repoinfo { int active_count; -int upkeep[O_COUNT]; +int upkeep[O_MAX]; int building_count; }; ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40612) Patch: migration
http://bugs.freeciv.org/Ticket/Display.html?id=40612 > > [matthias.pfaffer...@mapfa.de - Wed Dec 31 18:03:52 2008]: > > I get the following error; could it be related to the migration code > (remove_city() in make_city_migration())? I have not found a pattern > to narrow it down if it is the patch or the develop version of > freeciv. > > civserver: maphand.c:1564: map_claim_ownership: Assertion `((void *)0) > == playtile->site' failed. > > I suspect that after a city is remove something is messed up within > the server; but remove_city() is also used in similar kind in other > functions. Don't worry about that assertion too much; it is due to a known problem in the border code (40589). Sooner or later I will get to hunting it down. ;( --- 余命いくばくもない。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40616) patch: allow 2.1.8 to compile under sun studio community edition 11/08
http://bugs.freeciv.org/Ticket/Display.html?id=40616 > > [james.mccl...@gmail.com - Thu Jan 01 02:38:33 2009]: > > That patch that you attached completely fixes the problem > with repodlgs.c, but the change to helpdata.c that was in > the earlier patch(es) that I sent is also required to make > that file compile. Oh right, sorry I forgot about that. Here's a second version of the patch that should fix that problem by removing the macro. > Incidentally, I have to say that I do not know for > certain that those two fixes are sufficient to make the > code compile for any possible configuration. I have only > tried to compile the configuration that comes naturally > from the configuration script on my particular computer, > so I have not exercised all of the code that is there. > In particular, there appear to be a number of different > types of clients there, none of which I have looked at > other than the gtk one. Well if you feel like it and have some time to burn, you could try compiling with ./configure --enable-debug ./configure --enable-auth (maybe also --with-mysql-prefix) ./configure --enable-client=sdl These would be the main variations of interest to test, but it can wait if you have more pressing things to do at the moment. ;) --- 何なのかしら? diff --git a/client/gui-gtk-2.0/repodlgs.c b/client/gui-gtk-2.0/repodlgs.c index 7f40ea1..1272966 100644 --- a/client/gui-gtk-2.0/repodlgs.c +++ b/client/gui-gtk-2.0/repodlgs.c @@ -1178,7 +1178,7 @@ void activeunits_report_dialog_update(void) { struct repoinfo { int active_count; -int upkeep[O_COUNT]; +int upkeep[O_MAX]; int building_count; }; diff --git a/client/helpdata.c b/client/helpdata.c index 45850e2..2071502 100644 --- a/client/helpdata.c +++ b/client/helpdata.c @@ -237,42 +237,40 @@ static void insert_allows(struct req_source *psource, buf[0] = '\0'; /* FIXME: show other data like range and survives. */ -#define COREQ_APPEND(s) \ - (coreq_buf[0] != '\0' \ - ? cat_snprintf(coreq_buf, sizeof(coreq_buf), Q_("?clistmore:, %s"), (s)) \ - : sz_strlcpy(coreq_buf, (s))) - impr_type_iterate(impr_id) { struct impr_type *building = improvement_by_number(impr_id); requirement_vector_iterate(&building->reqs, req) { if (are_req_sources_equal(psource, &req->source)) { - char coreq_buf[512] = ""; - - requirement_vector_iterate(&building->reqs, coreq) { - if (!are_req_sources_equal(psource, &coreq->source)) { - char buf2[512]; - - COREQ_APPEND(get_req_source_text(&coreq->source, - buf2, sizeof(buf2))); - } - } requirement_vector_iterate_end; +char coreq_buf[512] = ""; + +requirement_vector_iterate(&building->reqs, coreq) { + if (!are_req_sources_equal(psource, &coreq->source)) { +char buf2[512] = ""; + +get_req_source_text(&coreq->source, buf2, sizeof(buf2)); +if (coreq_buf[0] == '\0') { + sz_strlcpy(coreq_buf, buf2); +} else { + cat_snprintf(coreq_buf, sizeof(coreq_buf), + Q_("?clistmore:, %s"), buf2); +} + } +} requirement_vector_iterate_end; if (coreq_buf[0] == '\0') { - cat_snprintf(buf, bufsz, _("Allows %s."), - improvement_name_translation(impr_id)); - } else { - cat_snprintf(buf, bufsz, _("Allows %s (with %s)."), - improvement_name_translation(impr_id), - coreq_buf); - } - cat_snprintf(buf, bufsz, "\n"); + cat_snprintf(buf, bufsz, _("Allows %s."), + improvement_name_translation(impr_id)); +} else { + cat_snprintf(buf, bufsz, _("Allows %s (with %s)."), + improvement_name_translation(impr_id), + coreq_buf); +} +cat_snprintf(buf, bufsz, "\n"); } } requirement_vector_iterate_end; } impr_type_iterate_end; - -#undef COREQ_APPEND } / ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
Re: [Freeciv-Dev] Costom nations and Dutch spelling
On 1/1/09, Jos Herrebrugh wrote: > Good Morning/afternoon/evening, > > Civilization 2 has an option that lets you make costom nations. for example: > Leader: Here you write the leader > Tribe: Here you write the nation's name > Adjective: Here you write the adjective of the nation's name. > There is also a button that lets you customize nation titles. For example i > wrote: > Anarchy: Anarchist > Despotism: Despotist > Monarchy: Monarchist > Etc. > I would like no i would love to see these two options on freeciv. It would > make a lot more out of > the gaming experience. See: http://freeciv.wikia.com/wiki/Rulesets > Now about the Dutch spelling: > I noted while playing the game that there where much language glitches for > example i used the diplomacy option with Hippo 3. They dont accept it: in > the message box there was noted: > This deal is not very good for us > Verbreek eerst je alliantie met Hippo 15 > > The first line i think should be Dutch but is English. > And the second line is Dutch as it should be. (it means: First you need to > break you alliance with Hippo 15) > Also the research window is called research and it should be: wetenschap. > Im noting this becouse im Dutch so im quite disappointed. See: http://freeciv.wikia.com/wiki/Translations --- 簡潔でもいいですか。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
Re: [Freeciv-Dev] debugging with Eclipse on Windows
On 1/1/09, Brandon Van Every wrote: > This is a tiring Hell that I don't want to be a part of anymore. I > guess nobody uses IDEs to debug Freeciv on Windows. Doesn't have to > be Eclipse, just somebody tell me something that works? Meanwhile, > I'm going to see if I can make a Visual Studio build out of this > thing. You could try gdb for debugging. It is true that freeciv development is more easily done on a gnu/linux system... unfortunately I would not know the best setup on windows. --- 知るわけないだろう。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40570) [Patch] marine explorers try to violate peace treaties and thus are stoped
http://bugs.freeciv.org/Ticket/Display.html?id=40570 > I have updated your patch according to the preceeding discussions, as it seemed a much easier solution than having to muck about in the ai_fill_unit_param internals. I replaced the "ignores zoc" condition with a check for whether the unit is a military unit or not. This way all units that would have to cancel a treaty to move into peaceful borders do not try to do so, while units that can move freely in peaceful territory go ahead and explore it (e.g. explorers, workers, settlers, diplomats, etc.). Also, some minor style/comment/formatting fixes and a version for trunk. --- 一緒に未踏の地を探検しませんか。 diff --git a/ai/aiexplorer.c b/ai/aiexplorer.c index 3f7ffde..ac2ecb7 100644 --- a/ai/aiexplorer.c +++ b/ai/aiexplorer.c @@ -63,6 +63,63 @@ static int likely_ocean(struct tile *ptile, struct player *pplayer) } /** + Returns TRUE if a unit owned by the given player can safely "explore" the + given tile. This mainly takes care that military units do not try to + move into another player's territory in violation of a treaty. +**/ +static bool ai_may_explore(const struct tile *ptile, + const struct player *pplayer, + const bv_flags unit_flags) +{ + /* Don't allow military units to cross borders. */ + if (!BV_ISSET(unit_flags, F_CIVILIAN) + && players_non_invade(tile_owner(ptile), pplayer)) { +return FALSE; + } + + /* Can't visit tiles with non-allied units. */ + if (is_non_allied_unit_tile(ptile, pplayer)) { +return FALSE; + } + + /* Non-allied cities are taboo even if no units are inside. */ + if (tile_city(ptile) && !pplayers_allied(tile_owner(ptile), pplayer)) { +return FALSE; + } + + return TRUE; +} + +/*** + TB function used by ai_explorer_goto(). +***/ +static enum tile_behavior ai_explorer_tb(const struct tile *ptile, + enum known_type k, + const struct pf_parameter *param) +{ + if (!ai_may_explore(ptile, param->owner, param->unit_flags)) { +return TB_IGNORE; + } + return TB_NORMAL; +} + +/*** + Constrained goto using ai_may_explore(). +***/ +static bool ai_explorer_goto(struct unit *punit, struct tile *ptile) +{ + struct pf_parameter parameter; + struct ai_risk_cost risk_cost; + + ai_fill_unit_param(¶meter, &risk_cost, punit, ptile); + parameter.get_TB = ai_explorer_tb; + + UNIT_LOG(LOG_DEBUG, punit, "ai_explorer_goto to %d,%d", + ptile->x, ptile->y); + return ai_unit_goto_constrained(punit, ptile, ¶meter); +} + +/** Return a value indicating how desirable it is to explore the given tile. In general, we want to discover unknown terrain of the opposite kind to our natural terrain, i.e. pedestrians like ocean and boats like land. @@ -114,12 +171,13 @@ static int explorer_desirable(struct tile *ptile, struct player *pplayer, int unknown = 0; /* First do some checks that would make a tile completely non-desirable. - * If there - * is a city on the tile, or if the tile is not accessible, or if the - * tile is on a different continent, or if we're a barbarian and - * the tile has a hut, don't go there. */ - if (tile_city(ptile) - || (is_barbarian(pplayer) && tile_has_special(ptile, S_HUT))) { + * If we're a barbarian and the tile has a hut, don't go there. */ + if (is_barbarian(pplayer) && tile_has_special(ptile, S_HUT)) { +return 0; + } + + /* Do no try to cross borders and break a treaty, etc. */ + if (!ai_may_explore(ptile, punit->owner, unit_type(punit)->flags)) { return 0; } @@ -298,7 +356,7 @@ enum unit_move_result ai_manage_explorer(struct unit *punit) if (best_tile != NULL) { /* TODO: read the path off the map we made. Then we can make a path * which goes beside the unknown, with a good EC callback... */ -if (!ai_unit_goto(punit, best_tile)) { +if (!ai_explorer_goto(punit, best_tile)) { /* Died? Strange... */ return MR_DEATH; } diff --git a/ai/aiexplorer.c b/ai/aiexplorer.c index 7f44a20..75fe158 100644 --- a/ai/aiexplorer.c +++ b/ai/aiexplorer.c @@ -108,6 +108,64 @@ static bool is_likely_trireme_loss(struct tile *ptile, struct player *pplayer, } /** + Returns TRUE if a unit owned by the given player can safely "explore" the + given tile. Th
[Freeciv-Dev] (PR#40612) Patch: migration
http://bugs.freeciv.org/Ticket/Display.html?id=40612 > > [guest - Thu Jan 01 03:28:31 2009]: > > > [matthias.pfaffer...@mapfa.de - Mi 31. Dez 2008, 18:03:52]: > > > > > - Use LOG_DEBUG not LOG_NORMAL for debugging messages. > > > > Oh, this was for me to test the patch; all set to debug now > > > > There is the possibility to activate DEBUG messages for only one file > and there only selected lines - how to do this? at the moment I don't > understand this part ... :-( I only know of the -d 4: syntax (see --help). The most annoying thing about that is that you get a load of verbose messages spam due to -d 3 automatically being set for every other file. Helpful in that case is to use the -l option and unique message prefixes (i.e. for grep). Most of the time I just put in printfs for debugging and remove them later. ;) --- いいじゃないか? ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40621) [Patch] Separate governor menu in city report
http://bugs.freeciv.org/Ticket/Display.html?id=40621 > Attached patch makes the "Citizen Governor" menu accessible from the main city report menu via a "Governor" menu item, rather than from "Production"/"Change"/"Citizen Governor". See: http://forum.freeciv.org/viewtopic.php?t=5737 --- 能がない知事は処刑される。 diff --git a/client/gui-gtk-2.0/cityrep.c b/client/gui-gtk-2.0/cityrep.c index f16e0a4..1cb3cb1 100644 --- a/client/gui-gtk-2.0/cityrep.c +++ b/client/gui-gtk-2.0/cityrep.c @@ -95,15 +95,17 @@ static void popup_last_menu(GtkMenuShell *menu, gpointer data); static void popup_first_menu(GtkMenuShell *menu, gpointer data); static void popup_next_menu(GtkMenuShell *menu, gpointer data); -static GtkWidget *city_center_command, *city_popup_command, *city_buy_command; +static GtkWidget *city_center_command; +static GtkWidget *city_popup_command; +static GtkWidget *city_buy_command; static GtkWidget *city_production_command; +static GtkWidget *city_governor_command; static GtkWidget *city_total_buy_cost_label; static GtkWidget *change_improvements_item; static GtkWidget *change_units_item; static GtkWidget *change_wonders_item; -static GtkWidget *change_cma_item; static GtkWidget *last_improvements_item; static GtkWidget *last_units_item; @@ -542,6 +544,11 @@ static void append_cma_to_menu_item(GtkMenuItem *parent_item, bool change_cma) struct cm_parameter parameter; GtkWidget *w; + w = gtk_menu_item_get_submenu(parent_item); + if (w != NULL && GTK_WIDGET_VISIBLE(w)) { +return; + } + gtk_menu_item_remove_submenu(parent_item); if (!can_client_issue_orders()) { return; @@ -713,6 +720,11 @@ static GtkWidget *create_city_report_menubar(void) gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); create_last_menu(item); + item = gtk_menu_item_new_with_mnemonic(_("Gover_nor")); + city_governor_command = item; + gtk_menu_shell_append(GTK_MENU_SHELL(menubar), item); + append_cma_to_menu_item(GTK_MENU_ITEM(item), TRUE); + item = gtk_menu_item_new_with_mnemonic(_("_Select")); gtk_menu_shell_append(GTK_MENU_SHELL(menubar), item); create_select_menu(item); @@ -1178,6 +1190,10 @@ void city_report_dialog_update(void) city_selection_changed_callback(city_selection); +if (GTK_WIDGET_SENSITIVE(city_governor_command)) { + append_cma_to_menu_item(GTK_MENU_ITEM(city_governor_command), TRUE); +} + select_menu_cached = FALSE; } } @@ -1233,8 +1249,6 @@ static void create_change_menu(GtkWidget *item) gtk_menu_shell_append(GTK_MENU_SHELL(menu), change_improvements_item); change_wonders_item = gtk_menu_item_new_with_label(_("Wonders")); gtk_menu_shell_append(GTK_MENU_SHELL(menu), change_wonders_item); - change_cma_item = gtk_menu_item_new_with_label(_("Citizen Governor")); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), change_cma_item); } / @@ -1317,7 +1331,6 @@ static void popup_change_menu(GtkMenuShell *menu, gpointer data) FALSE, TRUE, CO_CHANGE, can_city_build_now, G_CALLBACK(select_impr_or_unit_callback), n); - append_cma_to_menu_item(GTK_MENU_ITEM(change_cma_item), TRUE); } / @@ -1639,6 +1652,8 @@ static void city_selection_changed_callback(GtkTreeSelection *selection) gtk_widget_set_sensitive(city_production_command, n > 0 && can_client_issue_orders()); + gtk_widget_set_sensitive(city_governor_command, + n > 0 && can_client_issue_orders()); gtk_widget_set_sensitive(city_center_command, n > 0); gtk_widget_set_sensitive(city_popup_command, n > 0); gtk_widget_set_sensitive(city_buy_command, ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40618) randomize genlist
http://bugs.freeciv.org/Ticket/Display.html?id=40618 > > [matthias.pfaffer...@mapfa.de - Fri Jan 02 21:15:47 2009]: > > This patch adds the possibility to randomize the lists used by > freeciv. I think array_shuffle() would be better placed in utility/ shared.[ch], since it is useful for more than just genlists, and shared.h already has some array related stuff. Also, it should probably use myrand() from utility/rand.[ch] instead of the system rand(). This will make it possible to reproduce the same "random" behavior via seed parameters (e.g. mapseed, gameseed), which helps in debugging. Lastly, the two "for" lines in genlist_shuffle() are missing some spaces. ;) > I also replace the randomize algorithm in server/ > plrhand.c:shuffle_players(). Ok. --- トランプ手品は見たいですか。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40625) "Lake" tiles for 2.2, Amplio
http://bugs.freeciv.org/Ticket/Display.html?id=40625 > > [jwbj...@gmail.com - Mon Jan 05 03:13:15 2009]: > > It's not clear to me if caz has implemented the code for lakes > yet. I just wanted graphics to be ready. As far as I know lakes are defined in the terrain ruleset file (since the editor can place them) and the generator does create them (i.e. small oceans are turned into lakes). I'll try to figure out this complicated spec file syntax. ;) --- まだ喉が渇きませんか。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40624) Editor behavior when there is no military bases in ruleset
http://bugs.freeciv.org/Ticket/Display.html?id=40624 > > [cazf...@gmail.com - Sun Jan 04 21:38:32 2009]: > > Maybe it should be impossible to select military base tool at all > when ruleset has no base types at all. Currently it ends printing > error message "...because 0 is not a valid base type id" (this is not > too bad, at least it doesn't crash) Attached patch makes the editor gui popup an error message if the ruleset does not define any values for the tool the user tries to select. --- エラー。定義されていない現実。 client/editor.c | 30 ++ client/editor.h |1 + client/gui-gtk-2.0/editgui.c | 30 -- 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/client/editor.c b/client/editor.c index d5b89f8..a09be2c 100644 --- a/client/editor.c +++ b/client/editor.c @@ -270,6 +270,36 @@ bool editor_is_active(void) } / + Returns TRUE if the given tool should be made availble to the user via + the editor GUI. For example, this will return FALSE for ETT_MILITARY_BASE + if there are no bases defined in the ruleset. + + NB: This depends on the ruleset information received from the server, so + it will return FALSE if the client does not have it yet. +/ +bool editor_tool_is_usable(enum editor_tool_type ett) +{ + if (!editor || !(0 <= ett && ett < NUM_EDITOR_TOOL_TYPES)) { +return FALSE; + } + + switch (ett) { + case ETT_MILITARY_BASE: +return base_count() > 0; +break; + case ETT_TERRAIN_RESOURCE: +return resource_count() > 0; +break; + case ETT_UNIT: +return utype_count() > 0; +break; + default: +break; + } + return TRUE; +} + +/ Returns TRUE if the given tool type has sub-values (e.g. the terrain tool has values corresponding to the terrain types). / diff --git a/client/editor.h b/client/editor.h index 093c509..2388720 100644 --- a/client/editor.h +++ b/client/editor.h @@ -82,6 +82,7 @@ int editor_tool_get_applied_player(enum editor_tool_type ett); void editor_tool_set_applied_player(enum editor_tool_type, int player_no); +bool editor_tool_is_usable(enum editor_tool_type ett); bool editor_tool_has_value(enum editor_tool_type ett); bool editor_tool_has_value_erase(enum editor_tool_type ett); int editor_tool_get_value(enum editor_tool_type ett); diff --git a/client/gui-gtk-2.0/editgui.c b/client/gui-gtk-2.0/editgui.c index 2168cc2..4bb25ed 100644 --- a/client/gui-gtk-2.0/editgui.c +++ b/client/gui-gtk-2.0/editgui.c @@ -97,6 +97,7 @@ static void editbar_mode_button_toggled(GtkToggleButton *tb, gpointer userdata); static void editbar_tool_button_toggled(GtkToggleButton *tb, gpointer userdata); +static void try_to_set_editor_tool(enum editor_tool_type ett); static struct editbar *editor_toolbar; static struct editinfobox *editor_infobox; @@ -162,6 +163,31 @@ static void editbar_mode_button_toggled(GtkToggleButton *tb, } / + Try to set the given tool as the current editor tool. If the tool is + unavailable (editor_tool_is_usable) an error popup is displayed. +/ +static void try_to_set_editor_tool(enum editor_tool_type ett) +{ + if (!(0 <= ett && ett < NUM_EDITOR_TOOL_TYPES)) { +return; + } + + if (!editor_tool_is_usable(ett)) { +GtkWidget *dialog; +dialog = gtk_message_dialog_new(GTK_WINDOW(toplevel), +GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, +GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", +_("The current ruleset does not define any " + "objects corresponding to this editor tool.")); +gtk_window_set_title(GTK_WINDOW(dialog), editor_tool_get_name(ett)); +gtk_dialog_run(GTK_DIALOG(dialog)); +gtk_widget_destroy(dialog); + } else { +editor_set_tool(ett); + } +} + +/ Callback to handle toggling of any of the tool buttons. / static void editbar_tool_button_toggled(GtkToggleButton *tb, @@ -174,7 +200,7 @@ static void editbar_tool_button_toggled(GtkToggleButton *tb, ett = GPOINTER_TO_INT(userdata); if (active) { -editor_set_tool(ett); +try_to_set_editor_tool(ett); editgui_refresh(); } } @@ -1712,7 +1738,7 @@ gboolean handle_edit_key_press(GdkEventKey *ev) } if (new_ett != NU
[Freeciv-Dev] (PR#40610) auto_arrange_workers: Assertion `cmr.found_a_valid' failed.
http://bugs.freeciv.org/Ticket/Display.html?id=40610 > > [book - Sat Dec 27 20:10:43 2008]: > > > [guest - Sat Dec 27 19:12:10 2008]: > > > > Compiling with -O0 (before was -O2) like: > > ./configure --prefix=/home/users/vip/freeciv --enable-debug > > CFLAGS="-O0" and server stopped hanging up while building cities. > > So, gcc bug? > > Yes, it is looking more and more like the same situation we had > before, gcc 4.x optimizations break some parts of the code. I'll > try to find and "re-phrase" the code that is being miscompiled... I can confirm that the bug does not occur with gcc 4.3.2. :| --- Mへの最新版。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40610) auto_arrange_workers: Assertion `cmr.found_a_valid' failed.
http://bugs.freeciv.org/Ticket/Display.html?id=40610 > > [oliverburgh...@web.de - Wed Jan 07 12:17:16 2009]: > > > Freeciv server is crashing on my linux. > > reproduction: > start a game and create a city. When the first city of user or ai is > created the server crashes. > > version (both): > freeciv-2.1.8 build from sources > freeciv-2.1.8 prebuild fedora package > > system: > fedora 10 with all updates (7.1.2009) and no self build packages This is due to a bug in certain gcc 4.2 optimizations. Until the exact code that is miscomplied is found and replaced, compile with -O1 (or -O0), or upgrade gcc. --- 先祖に会いましょう。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40610) auto_arrange_workers: Assertion `cmr.found_a_valid' failed.
http://bugs.freeciv.org/Ticket/Display.html?id=40610 > > [guest - Wed Jan 07 23:12:40 2009]: > > I am using gcc 4.3.2, > but by using "-O1" it works - thanks. This is strange. I thought the assertion was being triggered due to miscompiled code caused by a bug in gcc 4.2, that has since been fixed in gcc 4.3. I even tested the default compile of 2.1.8 with gcc 4.3.2 and I did not get the assertion failure. Perhaps then redhat added some custom patches to its gcc? > $ gcc -v > Es werden eingebaute Spezifikationen verwendet. > Ziel: i386-redhat-linux > Konfiguriert mit: ../configure --prefix=/usr --mandir=/usr/share/man > --infodir=/usr/share/info > --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap > --enable-shared --enable-threads=posix --enable-checking=release > --with-system-zlib --enable-__cxa_atexit --disable-libunwind- exceptions > --enable-languages=c,c++,objc,obj-c++,java,fortran,ada > --enable-java-awt=gtk --disable-dssi --enable-plugin > --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre > --enable-libgcj-multifile --enable-java-maintainer-mode > --with-ecj-jar=/usr/share/java/eclipse-ecj.jar > --disable-libjava-multilib --with-cpu=generic --build=i386-redhat- linux > Thread-Modell: posix > gcc-Version 4.3.2 20081105 (Red Hat 4.3.2-7) (GCC) For comparison on my machine: $ gcc -v Using built-in specs. Target: i686-pc-linux-gnu Configured with: ../gcc-4.3.2/configure --prefix=/usr Thread model: posix gcc version 4.3.2 (GCC) :( --- 元気出して。とにかく、近頃はその種の帽子をかぶらないよね。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40177) [Patched] Shared common library
http://bugs.freeciv.org/Ticket/Display.html?id=40177 > > [cazf...@gmail.com - Thu Jan 08 00:15:25 2009]: > > 2008/11/10 Marko Lindqvist: > > > > About status of this ticket: Some windows compilations (SDL > > client, build with nls) fail with this patch. > > Fixed. > > Please test. I plan to commit this version if nobody > reports problems. I tested the patch on linux with the gtk, sdl and xaw clients configured and it seems to work well. Maybe dummy.c could be renamed civclient.c and the existing civclient.[ch] renamed to client.[ch]? Or perhaps client_main.[ch] would be a better name, since there is already "clinet". It's just that calling it "dummy" makes it look like a hack... :/ I guess it should have the full copyright notice at the top too, and a comment about where the real civclient "main" function is, in case future would- be programmers go looking for it there. > +# FIXME: Server library is calling AI functions. > +#We should get rid of this dependency. I agree that this should be addressed; it really deserves its own full ticket. --- 先週の土曜日参照の迷宮で迷子になってしまった。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40644) [Patch] Iteration support to scripting
http://bugs.freeciv.org/Ticket/Display.html?id=40644 > > [cazf...@gmail.com - Thu Jan 08 20:25:03 2009]: > > Attached patch adds support to iterate though players, cities, and > units to lua scripting. > > I decided not to use iterator objects with all the memory handling > they would require. It would be nice if one could do for player in game:players() do print player:name()-- or whatever end Lua has a lot of great features for implementing iteration cleanly and efficiently: closures, generic for, coroutines, and object oriented syntax (see http://www.lua.org/pil/). It would be a shame not to make the best use of them. ;) > Instead, script can call iterate_[players|cities|units]() > and that emits script signal for each item of the type. I don't think making a call to script_signal_emit during every iteration of the loop is very efficient. Considering that there could be hundreds of cities and units, and that iteration is a very basic, often used algorithm, this could result in a significant performance penalty. Add to that that the X_iterate_safe macros make a stack array copy of the entire list. This seems like a large price to pay just to allow users to destroy objects while they are being iterated over. :( Of course I could be wrong; I have not actually profiled the code with general test cases to see where the real bottleneck would be... --- 俺に物体を投げるのはよせ! ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40643) Bug: Granary but food not half full after shrink
http://bugs.freeciv.org/Ticket/Display.html?id=40643 > > [bart.demey...@esperanto.be - Thu Jan 08 20:11:15 2009]: > > freeciv version 2.1.5 > Ubuntu 8.10 > > In my first cities I build first a granary, when I afterwords > build a settler my food is for example 5/20, while it should > at least be 10/20. When the city grows, it rightfully goes to > 15/30. A granary only half-fills city food stock when the city grows or shrinks due to food. As far as I know, it has no effect when settlers are produced/added, citizens die during an attack, etc. This is just the way the game rules are implemented (I checked back as far as 2.0). I suppose the granary help text is a little misleading in this respect, and could be clarified... --- 食べちゃったんだ。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40646) Use XOR for selection rectangle drawing
http://bugs.freeciv.org/Ticket/Display.html?id=40646 > Attached patch changes the selection rectangle drawing code to use xor instead overwriting pixel values. This means that it can be erased by just drawing over itself again, rather than redrawing all of the sprites at all of the tiles that it touches. This is much more efficient than the existing code, but of course animations and such will now affect it. Since the situations where animations are occurring and the user is simulatneously using the selection rectangle are rare (I assume), I would hope that this is not too much of a problem. I tested the gtk, sdl and xaw guis. Apparently there is not way to use the selection rectangle in sdl and xaw, so I did not modify their draw_selection_rectangle() functions. --- 私は長方形に住んでいる。 client/editor.c | 43 - client/editor.h |1 - client/gui-ftwl/mapview.c |2 - client/gui-gtk-2.0/gui_main.c |4 +++ client/gui-gtk-2.0/gui_main.h |1 + client/gui-gtk-2.0/mapview.c | 22 +++- client/gui-sdl/mapview.c |1 - client/gui-win32/mapview.c|1 - client/gui-xaw/mapview.c |1 - client/mapctrl_common.c | 18 ++-- client/mapctrl_common.h |1 - client/mapview_common.c |7 -- 12 files changed, 45 insertions(+), 57 deletions(-) diff --git a/client/editor.c b/client/editor.c index 1f6be9e..a517ee8 100644 --- a/client/editor.c +++ b/client/editor.c @@ -670,6 +670,24 @@ void editor_mouse_button_release(int canvas_x, int canvas_y, } / + Draws the editor selection rectangle using draw_selection_rectangle(). +/ +static void editor_draw_selrect(void) +{ + if (!editor) { +return; + } + + if (editor->selrect_active && editor->selrect_width > 0 + && editor->selrect_height > 0) { +draw_selection_rectangle(editor->selrect_x, + editor->selrect_y, + editor->selrect_width, + editor->selrect_height); + } +} + +/ Handle a change in the size of the selection rectangle. The given point is the new extremity of the rectangle. / @@ -693,8 +711,8 @@ static void editor_resize_selection_rectangle(int canvas_x, int canvas_y) y2 = editor->selrect_start_y; } - dirty_all(); - flush_dirty(); + /* Erase the previously drawn rectangle. */ + editor_draw_selrect(); if (x1 == x2 || y1 == y2) { editor->selrect_width = 0; @@ -707,7 +725,7 @@ static void editor_resize_selection_rectangle(int canvas_x, int canvas_y) editor->selrect_width = x2 - x1; editor->selrect_height = y2 - y1; - editor_redraw(); + editor_draw_selrect(); } / @@ -892,25 +910,6 @@ const struct tile *editor_get_current_tile(void) } / - Redraw any editor-specific decorations. This should usually be called - whenever the map canvas is redrawn. -/ -void editor_redraw(void) -{ - if (!editor) { -return; - } - - if (editor->selrect_active && editor->selrect_width > 0 - && editor->selrect_height > 0) { -draw_selection_rectangle(editor->selrect_x, - editor->selrect_y, - editor->selrect_width, - editor->selrect_height); - } -} - -/ Toggle the current tool mode between the given mode and ETM_PAINT. / void editor_tool_toggle_mode(enum editor_tool_type ett, diff --git a/client/editor.h b/client/editor.h index 093c509..53d4dfc 100644 --- a/client/editor.h +++ b/client/editor.h @@ -120,7 +120,6 @@ void editor_mouse_button_press(int canvas_x, int canvas_y, void editor_mouse_button_release(int canvas_x, int canvas_y, int button, int modifiers); void editor_mouse_move(int canvas_x, int canvas_y, int modifiers); -void editor_redraw(void); void editor_apply_tool(const struct tile *ptile, bool part_of_selection); diff --git a/client/gui-ftwl/mapview.c b/client/gui-ftwl/mapview.c index 536a22a..14cc77b 100644 --- a/client/gui-ftwl/mapview.c +++ b/client/gui-ftwl/mapview.c @@ -860,7 +860,6 @@ static void my_drag_move(struct sw_widget *widget, dy, new_x, new_y); set_map
[Freeciv-Dev] (PR#40648) [Editor] Player gold editable property
http://bugs.freeciv.org/Ticket/Display.html?id=40648 > Implements a property for modifying the amount of gold in the player's treasury. Arbitrary maximum of 100. ;) --- もう少しお金はどうですか。 client/gui-gtk-2.0/editprop.c | 17 + server/edithand.c | 14 ++ 2 files changed, 31 insertions(+), 0 deletions(-) diff --git a/client/gui-gtk-2.0/editprop.c b/client/gui-gtk-2.0/editprop.c index 8c0863c..1aa4a32 100644 --- a/client/gui-gtk-2.0/editprop.c +++ b/client/gui-gtk-2.0/editprop.c @@ -314,6 +314,7 @@ enum object_property_ids { OPID_PLAYER_NATION, OPID_PLAYER_ADDRESS, OPID_PLAYER_INVENTIONS, + OPID_PLAYER_GOLD, OPID_GAME_YEAR }; @@ -1543,6 +1544,9 @@ static struct propval *objbind_get_value_from_object(struct objbind *ob, } advance_index_iterate_end; pv->must_free = TRUE; break; +case OPID_PLAYER_GOLD: + pv->data.v_int = pplayer->economic.gold; + break; default: freelog(LOG_ERROR, "Unhandled request for value of property %d " "(%s) from object of type \"%s\" in " @@ -1701,6 +1705,12 @@ static bool objbind_get_allowed_value_span(struct objbind *ob, } else if (objtype == OBJTYPE_PLAYER) { switch (propid) { +case OPID_PLAYER_GOLD: + min = 0; + max = 100; /* Arbitrary. */ + step = 1; + big_step = 100; + break; default: freelog(LOG_ERROR, "Unhandled request for value range of " "property %d (%s) from object of type \"%s\" in " @@ -2161,6 +2171,9 @@ static void objbind_pack_modified_value(struct objbind *ob, packet->inventions[tech] = pv->data.v_inventions[tech]; } advance_index_iterate_end; break; +case OPID_PLAYER_GOLD: + packet->gold = pv->data.v_int; + break; default: freelog(LOG_ERROR, "Unhandled request to pack value of " "property %d (%s) from object of type \"%s\" in " @@ -2549,6 +2562,7 @@ static void objprop_setup_widget(struct objprop *op) case OPID_CITY_SIZE: case OPID_CITY_SHIELD_STOCK: + case OPID_PLAYER_GOLD: case OPID_GAME_YEAR: spin = gtk_spin_button_new_with_range(0.0, 100.0, 1.0); g_signal_connect(spin, "value-changed", @@ -2724,6 +2738,7 @@ static void objprop_refresh_widget(struct objprop *op, case OPID_CITY_SIZE: case OPID_CITY_SHIELD_STOCK: + case OPID_PLAYER_GOLD: case OPID_GAME_YEAR: spin = objprop_get_child_widget(op, "spin"); if (pv) { @@ -3669,6 +3684,8 @@ static void property_page_setup_objprops(struct property_page *pp) | OPF_HAS_WIDGET | OPF_EDITABLE, VALTYPE_NATION); ADDPROP(OPID_PLAYER_INVENTIONS, _("Inventions"), OPF_IN_LISTVIEW | OPF_HAS_WIDGET | OPF_EDITABLE, VALTYPE_INVENTIONS_ARRAY); +ADDPROP(OPID_PLAYER_GOLD, _("Gold"), OPF_IN_LISTVIEW +| OPF_HAS_WIDGET | OPF_EDITABLE, VALTYPE_INT); break; case OBJTYPE_GAME: diff --git a/server/edithand.c b/server/edithand.c index 46f0612..b80ec90 100644 --- a/server/edithand.c +++ b/server/edithand.c @@ -1012,6 +1012,20 @@ void handle_edit_player(struct connection *pc, update_research = TRUE; } advance_index_iterate_end; + /* Handle a change in the player's gold. */ + if (packet->gold != pplayer->economic.gold) { +if (!(0 <= packet->gold && packet->gold <= 100)) { + notify_conn(pc->self, NULL, E_BAD_COMMAND, + _("Cannot set gold for player %d (%s) because " +"the value %d is outside the allowed range."), + player_number(pplayer), player_name(pplayer), + packet->gold); +} else { + pplayer->economic.gold = packet->gold; + changed = TRUE; +} + } + /* TODO: Handle more property edits. */ ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40644) [Patch] Iteration support to scripting
http://bugs.freeciv.org/Ticket/Display.html?id=40644 > > [cazf...@gmail.com - Fri Jan 09 13:32:08 2009]: > > 2009/1/8 Madeline Book: > > > > It would be nice if one could do > > > > for player in game:players() do > > print player:name()-- or whatever > > end > > > > Lua has a lot of great features for implementing iteration > > cleanly and efficiently: closures, generic for, coroutines, > > and object oriented syntax (see http://www.lua.org/pil/). > > It would be a shame not to make the best use of them. ;) > > True, but that does sounds more like 2.3 stuff. I don't see it > happening in 2.2 timeframe. > > I'm somewhat undecided if we should just not include any iteration > support at all at 2.2, or should we include something like my patch > for situations where modder desperately needs at least some kind of > iteration support. I agree that something is better than nothing. I'm just unsure how much more work an efficient implementation would be. I guess the above patch is ok for now... --- 失礼しました。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40611) default.serv sets startunits to cccwwx
http://bugs.freeciv.org/Ticket/Display.html?id=40611 > > [guest - Mon Jan 05 12:28:43 2009]: > > > [book - So 28. Dez 2008, 04:24:04]: > > > > > [bvanev...@gmail.com - Sat Dec 27 22:33:31 2008]: > > > > > > [...] > > > > > > Solution: change line in default.serv to ccwwx > > > > Ok. > > The patch seems to be added to trunk? Yes, it would appear this was already fixed in trunk. --- この日はもう起こったか。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40616) patch: allow 2.1.8 to compile under sun studio community edition 11/08
http://bugs.freeciv.org/Ticket/Display.html?id=40616 > > [james.mccl...@gmail.com - Thu Jan 01 04:14:04 2009]: > > Hello, > > I can confirm that the gtk 2 client does compile smoothly with > the patch that you sent applied. I can also build with the > "--enable-debug" and "--enable-client=sdl" versions. I have > not tried the other two. For completeness here is a version of the patch for trunk too (and a minor formatting fix for the S2_1 version). --- 機知に富んだ何かがここにあったが、もう出た。 diff --git a/client/gui-gtk-2.0/repodlgs.c b/client/gui-gtk-2.0/repodlgs.c index 587cd69..bf9c920 100644 --- a/client/gui-gtk-2.0/repodlgs.c +++ b/client/gui-gtk-2.0/repodlgs.c @@ -1200,7 +1200,7 @@ void activeunits_report_dialog_update(void) { struct repoinfo { int active_count; -int upkeep[O_COUNT]; +int upkeep[O_MAX]; int building_count; }; diff --git a/client/helpdata.c b/client/helpdata.c index 7920a58..a781794 100644 --- a/client/helpdata.c +++ b/client/helpdata.c @@ -259,39 +259,39 @@ static void insert_allows(struct universal *psource, buf[0] = '\0'; /* FIXME: show other data like range and survives. */ -#define COREQ_APPEND(s) \ - (coreq_buf[0] != '\0' \ - ? cat_snprintf(coreq_buf, sizeof(coreq_buf), Q_("?clistmore:, %s"), (s)) \ - : sz_strlcpy(coreq_buf, (s))) improvement_iterate(pimprove) { requirement_vector_iterate(&pimprove->reqs, req) { if (are_universals_equal(psource, &req->source)) { - char coreq_buf[512] = ""; - - requirement_vector_iterate(&pimprove->reqs, coreq) { - if (!are_universals_equal(psource, &coreq->source)) { - char buf2[512]; - - COREQ_APPEND(universal_name_translation(&coreq->source, - buf2, sizeof(buf2))); - } - } requirement_vector_iterate_end; - - if (coreq_buf[0] == '\0') { - cat_snprintf(buf, bufsz, _("Allows %s."), - improvement_name_translation(pimprove)); - } else { - cat_snprintf(buf, bufsz, _("Allows %s (with %s)."), - improvement_name_translation(pimprove), - coreq_buf); - } - cat_snprintf(buf, bufsz, "\n"); +char coreq_buf[512] = ""; + +requirement_vector_iterate(&pimprove->reqs, coreq) { + if (!are_universals_equal(psource, &coreq->source)) { +char buf2[512] = ""; + +universal_name_translation(&coreq->source, buf2, + sizeof(buf2)); +if (coreq_buf[0] == '\0') { + sz_strlcpy(coreq_buf, buf2); +} else { + cat_snprintf(coreq_buf, sizeof(coreq_buf), + Q_("?clistmore:, %s"), buf2); +} + } +} requirement_vector_iterate_end; + +if (coreq_buf[0] == '\0') { + cat_snprintf(buf, bufsz, _("Allows %s."), + improvement_name_translation(pimprove)); +} else { + cat_snprintf(buf, bufsz, _("Allows %s (with %s)."), + improvement_name_translation(pimprove), + coreq_buf); +} +cat_snprintf(buf, bufsz, "\n"); } } requirement_vector_iterate_end; } improvement_iterate_end; - -#undef COREQ_APPEND } / diff --git a/client/gui-gtk-2.0/repodlgs.c b/client/gui-gtk-2.0/repodlgs.c index 7f40ea1..1272966 100644 --- a/client/gui-gtk-2.0/repodlgs.c +++ b/client/gui-gtk-2.0/repodlgs.c @@ -1178,7 +1178,7 @@ void activeunits_report_dialog_update(void) { struct repoinfo { int active_count; -int upkeep[O_COUNT]; +int upkeep[O_MAX]; int building_count; }; diff --git a/client/helpdata.c b/client/helpdata.c index 45850e2..fa8f6be 100644 --- a/client/helpdata.c +++ b/client/helpdata.c @@ -237,42 +237,40 @@ static void insert_allows(struct req_source *psource, buf[0] = '\0'; /* FIXME: show other data like range and survives. */ -#define COREQ_APPEND(s) \ - (coreq_buf[0] != '\0' \ - ? cat_snprintf(coreq_buf, sizeof(coreq_buf), Q_("?clistmore:, %s"), (s)) \ - : sz_strlcpy(coreq_buf, (s))) - impr_type_iterate(impr_id) { struct impr_type *building = improvement_by_number(impr_id); requirement_vector_iterate(&building->reqs, req) { if (are_req_sources_equal(psource, &req->source)) { - char coreq_buf[512] = ""; - - requirement_vector_iterate(&building->reqs, coreq) { - if (!are_req_sources_equal(psource, &coreq->source)) { - char buf2[512]; - - COREQ_APPEND(get_req_source_text(&coreq->source, - buf2, sizeof(buf2))); - } - } requirement_vector_iterate_end; +char coreq_buf[512] = ""; + +requirement_vector_iterate(&building->reqs, coreq) { + if (!are_req_sources_equal(psource, &coreq->source)) { +char buf2[512] = ""; + +get_req_source_text(&coreq->source, buf2, sizeof(buf2)); +if (coreq_buf[0] == '\
[Freeciv-Dev] (PR#40655) [Patch] Notify player of alliance problem on treaty fail
http://bugs.freeciv.org/Ticket/Display.html?id=40655 > If a user tries to ally with another player and is at war with one of their allies, the server correctly disallows the alliance, but does not notify the user of the reason. The accept button just does nothing, leaving the user wondering if there is a bug of something. The attached patch makes the server send the reason why the treaty fails. -- 敵の敵はうるさいやつだな。 diff --git a/server/diplhand.c b/server/diplhand.c index 974a8d2..d878b40 100644 --- a/server/diplhand.c +++ b/server/diplhand.c @@ -215,6 +215,12 @@ void handle_diplomacy_accept_treaty_req(struct player *pplayer, break; case CLAUSE_ALLIANCE: diplcheck = pplayer_can_make_treaty(pplayer, pother, DS_ALLIANCE); + if (diplcheck == DIPL_ALLIANCE_PROBLEM) { +notify_player(pplayer, NULL, E_DIPLOMACY, + _("You cannot form an alliance because you are " +"at war with one of %s's allies."), + player_name(pplayer)); + } if (diplcheck != DIPL_OK) { return; } ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40655) [Patch] Notify player of alliance problem on treaty fail
http://bugs.freeciv.org/Ticket/Display.html?id=40655 > > [cazf...@gmail.com - Sun Jan 11 14:21:43 2009]: > > 2009/1/10 Madeline Book: > > > > If a user tries to ally with another player and is at war > > with one of their allies, the server correctly disallows > > the alliance, but does not notify the user of the reason. > > The accept button just does nothing, leaving the user > > wondering if there is a bug of something. The attached > > patch makes the server send the reason why the treaty fails. > > Shouldn't either 'pplayer' be 'pother'? Seems like you are claiming > that player is in war with his/her own ally. Correct. I made a mistake in the player_name() argument. --- 解離性同一性障害 diff --git a/server/diplhand.c b/server/diplhand.c index 974a8d2..e8d71ab 100644 --- a/server/diplhand.c +++ b/server/diplhand.c @@ -215,6 +215,12 @@ void handle_diplomacy_accept_treaty_req(struct player *pplayer, break; case CLAUSE_ALLIANCE: diplcheck = pplayer_can_make_treaty(pplayer, pother, DS_ALLIANCE); + if (diplcheck == DIPL_ALLIANCE_PROBLEM) { +notify_player(pplayer, NULL, E_DIPLOMACY, + _("You cannot form an alliance because you are " +"at war with an ally of %s."), + player_name(pother)); + } if (diplcheck != DIPL_OK) { return; } ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40658) [Patch] No teleporting to resolve stacks
http://bugs.freeciv.org/Ticket/Display.html?id=40658 > When an alliance is cancelled the server tries to resolve unit stacks by teleporting "illegal" units to the nearest city of their owner. By cleverly arranging stacks of units and swapping key cities, two players can thus purposely teleport units a theoretically infinite distance (by chaining multiple teleports) so long as the units have moves left and diplomacy allows alliances to be continually reformed. This kind of abuse of an unintended "feature" is generally not appreciated by players (e.g. see discussion on the longturn site). The attached patch changes the function bounce_unit() to move a unit to a random tile a maximum of two tiles away from its current position, chosen from a list of tiles where the unit can survive (can_unit_survive_at_tile()) and that is not currently occupied by a non-ally unit or city. If no such tiles exist, then the unit is disbanded. --- 魔導士は暴露に感謝しなかった。 diff --git a/server/unittools.c b/server/unittools.c index cf4263f..6748158 100644 --- a/server/unittools.c +++ b/server/unittools.c @@ -1114,25 +1114,56 @@ bool teleport_unit_to_city(struct unit *punit, struct city *pcity, } /** - Teleport or remove a unit due to stack conflict. + Move or remove a unit due to stack conflicts. This function will try to + find a random safe tile within a two tile distance of the unit's current + tile and move the unit there. If no tiles are found, the unit is + disbanded. If 'verbose' is TRUE, a message is sent to the unit owner + regarding what happened. **/ void bounce_unit(struct unit *punit, bool verbose) { - struct player *pplayer = unit_owner(punit); - struct city *pcity = find_closest_owned_city(pplayer, punit->tile, - is_sailing_unit(punit), NULL); + struct player *pplayer; + struct tile *punit_tile; + const int DIST = 2; + struct tile *tiles[4 * DIST * DIST + 4 * DIST + 1]; + int count = 0; + + if (!punit) { +return; + } + + pplayer = unit_owner(punit); + punit_tile = unit_tile(punit); + + square_iterate(punit_tile, DIST, ptile) { +if (count >= ARRAY_SIZE(tiles)) { + break; +} +if (can_unit_survive_at_tile(punit, ptile) +&& !is_non_allied_city_tile(ptile, pplayer) +&& !is_non_allied_unit_tile(ptile, pplayer)) { + tiles[count++] = ptile; +} + } square_iterate_end; + + if (count > 0) { +struct tile *ptile = tiles[myrand(count)]; - if (pcity && can_unit_exist_at_tile(punit, pcity->tile)) { -(void) teleport_unit_to_city(punit, pcity, 0, verbose); - } else { -/* remove it */ if (verbose) { - notify_player(unit_owner(punit), punit->tile, E_UNIT_LOST_MISC, - _("Disbanded your %s."), - unit_name_translation(punit)); + notify_player(pplayer, ptile, E_UNIT_RELOCATED, _("Moved your %s."), +unit_name_translation(punit)); } -wipe_unit(punit); +move_unit(punit, ptile, 0); +return; + } + + /* Didn't find a place to bounce the unit, just disband it. */ + if (verbose) { +notify_player(pplayer, punit_tile, E_UNIT_LOST_MISC, + _("Disbanded your %s."), + unit_name_translation(punit)); } + wipe_unit(punit); } diff --git a/server/unittools.c b/server/unittools.c index 455a9bb..f8ebb99 100644 --- a/server/unittools.c +++ b/server/unittools.c @@ -1024,25 +1024,56 @@ bool teleport_unit_to_city(struct unit *punit, struct city *pcity, } /** - Teleport or remove a unit due to stack conflict. + Move or remove a unit due to stack conflicts. This function will try to + find a random safe tile within a two tile distance of the unit's current + tile and move the unit there. If no tiles are found, the unit is + disbanded. If 'verbose' is TRUE, a message is sent to the unit owner + regarding what happened. **/ void bounce_unit(struct unit *punit, bool verbose) { - struct player *pplayer = unit_owner(punit); - struct city *pcity = find_closest_owned_city(pplayer, punit->tile, - is_sailing_unit(punit), NULL); + struct player *pplayer; + struct tile *punit_tile; + const int DIST = 2; + struct tile *tiles[4 * DIST * DIST + 4 * DIST + 1]; + int count = 0; + + if (!punit) { +return; + } + + pplayer = unit_owner(punit); + punit_tile = punit->tile; + + square_iterate(punit_tile, DIST, ptile) { +if (count >= ARRAY_SIZE(tiles)) { + break; +} +if (can_unit_survive_at_tile(punit, ptile) +&& !is_non_allied_city_tile(ptile, pplayer) +&& !is_non_allied_unit_tile(ptile, p
Re: [Freeciv-Dev] explorers can pillage. a bug?
On 1/10/09, Brandon Van Every wrote: > I learned that in the default rules an explorer can pillage. This > strikes me as a bug. Why should a non-military unit, able to move > through a peaceful border, be allowed to pillage? Or does peace > itself prevent pillaging? Anyways, seems like an awfully tough > explorer. Big work crew following him? I could understand if a > worker can pillage, but not an explorer. This is just how the game rules have always been, and I don't particularly mind. Maybe a ruleset setting could be made that controls whether non-worker civilian units can pillage. --- 探検するから、強くなった。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
Re: [Freeciv-Dev] building a city always loses connection with server
On 1/14/09, Dominique Leuenberger wrote: On 1/14/2009 at 4:41 PM, "Marko Lindqvist" wrote: >> 2009/1/14 Dominique Leuenberger : >>> Good day everybody, >>> >>> I'm part of the team building RPMs for openSUSE. Today we got a report >>> from >> a user of freeciv that, whenever he creates a city in online mode, his >>> client disconnects. >> >> Which version of gcc? There used to be problem just like this caused >> by gcc 4.2.1 & 4.2.2 miscompilation when optimization level -O2 is >> used. Even if you are using 4.3.x gcc, you may want to test with lower >> optimization level. >> >> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33381 > > Thank you very much for the reply. > The user reported it against openSUSE 11.1, which means it is compiled with > gcc 4.3 This was reported before; for even more information see our ticket: http://bugs.freeciv.org/Ticket/Display.html?id=40610 Stock gcc 4.3 compiles freeciv fine even with -O2 (at least that is true on my system). I suspect that certain distros have added patches to their gcc which are now causing certain code to be miscompiled. -O1 fixes it, but it is possible that disabling just the optimizations caused by the custom patches would also fix the problem. --- 小さな手落ち、大きな結果。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40661) sun cc compile fail because enum array
http://bugs.freeciv.org/Ticket/Display.html?id=40661 > > [halton@sun.com - Thu Jan 15 03:47:27 2009]: > > Hi, > > I'm compiling freeciv-2.1.8 with sun cc, and I get following > > source='helpdata.c' object='helpdata.o' libtool=no \ > DEPDIR= depmode=none /bin/bash ../bootstrap/depcomp \ > /opt/SUNWspro/bin/cc -DHAVE_CONFIG_H -I. -I.. -I../utility -I./ include > -I../common -I../common/aicore -I../intl -I./agents -D_REENTRANT > -D_POSIX_PTHREAD_SEMANTICS -I/usr/include/gtk-2.0 > -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo > -I/usr/include/pango-1.0 -I/usr/X11/include -I/usr/include/glib-2.0 > -I/usr/lib/glib-2.0/include -I/usr/include/pixman-1 > -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/SDL > -D_GNU_SOURCE=1 -D_REENTRANT -I /usr/include -I /usr/include > -I /usr/include -DLOCALEDIR="\"/usr/share/locale\"" > -DDEFAULT_DATA_PATH="\".:data:~/.freeciv:/usr/share/freeciv\"" -i - xO4 > -xspace -xstrconst -xpentium -mr -xregs=no%frameptr -xchar=signed -c > helpdata.c > "helpdata.c", line 257: operands have incompatible types: > int ":" void > cc: acomp failed for helpdata.c > > Attachment is patch for this bug. A similar fix has already been committed to svn. See: http://bugs.freeciv.org/Ticket/Display.html?id=40616 --- 同僚がもうしました。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40662) [Patch] Somewhat clearer client hack messages
http://bugs.freeciv.org/Ticket/Display.html?id=40662 > This was suggested on freeciv-i18n by Sini Ruohomaa. --- 驚かないでください。我々はあなたのまぶたを支配しています。 diff --git a/client/connectdlg_common.c b/client/connectdlg_common.c index 3cf8ead..9f26b6e 100644 --- a/client/connectdlg_common.c +++ b/client/connectdlg_common.c @@ -467,13 +467,14 @@ void handle_single_want_hack_reply(bool you_have_hack) } if (you_have_hack) { -append_output_window(_("We have control of the server " - "(command access level hack)")); +append_output_window(_("Established control over the server. " + "You have command access level 'hack'.")); client_has_hack = TRUE; } else if (is_server_running()) { /* only output this if we started the server and we NEED hack */ -append_output_window(_("We can't take control of server, " - "attempting to kill it.")); +append_output_window(_("Failed to obtain the required access " + "level to take control of the server. " + "The server will now be shutdown.")); client_kill_server(TRUE); } } ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40648) [Editor] Player gold editable property
http://bugs.freeciv.org/Ticket/Display.html?id=40648 > > [book - Thu Jan 08 23:30:14 2009]: > > Implements a property for modifying the amount of gold > in the player's treasury. Arbitrary maximum of 100. ;) Forgot to set the packet field in objbind_pack_current_values(). --- 詳細だね。 client/gui-gtk-2.0/editprop.c | 18 ++ server/edithand.c | 14 ++ 2 files changed, 32 insertions(+), 0 deletions(-) diff --git a/client/gui-gtk-2.0/editprop.c b/client/gui-gtk-2.0/editprop.c index 3255f55..e5f744b 100644 --- a/client/gui-gtk-2.0/editprop.c +++ b/client/gui-gtk-2.0/editprop.c @@ -317,6 +317,7 @@ enum object_property_ids { OPID_PLAYER_NATION, OPID_PLAYER_ADDRESS, OPID_PLAYER_INVENTIONS, + OPID_PLAYER_GOLD, OPID_GAME_YEAR }; @@ -1546,6 +1547,9 @@ static struct propval *objbind_get_value_from_object(struct objbind *ob, } advance_index_iterate_end; pv->must_free = TRUE; break; +case OPID_PLAYER_GOLD: + pv->data.v_int = pplayer->economic.gold; + break; default: freelog(LOG_ERROR, "Unhandled request for value of property %d " "(%s) from object of type \"%s\" in " @@ -1704,6 +1708,12 @@ static bool objbind_get_allowed_value_span(struct objbind *ob, } else if (objtype == OBJTYPE_PLAYER) { switch (propid) { +case OPID_PLAYER_GOLD: + min = 0; + max = 100; /* Arbitrary. */ + step = 1; + big_step = 100; + break; default: freelog(LOG_ERROR, "Unhandled request for value range of " "property %d (%s) from object of type \"%s\" in " @@ -2011,6 +2021,7 @@ static void objbind_pack_current_values(struct objbind *ob, packet->inventions[tech] = TECH_KNOWN == player_invention_state(pplayer, tech); } advance_index_iterate_end; +packet->gold = pplayer->economic.gold; /* TODO: Set more packet fields. */ } else if (objtype == OBJTYPE_GAME) { @@ -2164,6 +2175,9 @@ static void objbind_pack_modified_value(struct objbind *ob, packet->inventions[tech] = pv->data.v_inventions[tech]; } advance_index_iterate_end; break; +case OPID_PLAYER_GOLD: + packet->gold = pv->data.v_int; + break; default: freelog(LOG_ERROR, "Unhandled request to pack value of " "property %d (%s) from object of type \"%s\" in " @@ -2552,6 +2566,7 @@ static void objprop_setup_widget(struct objprop *op) case OPID_CITY_SIZE: case OPID_CITY_SHIELD_STOCK: + case OPID_PLAYER_GOLD: case OPID_GAME_YEAR: spin = gtk_spin_button_new_with_range(0.0, 100.0, 1.0); g_signal_connect(spin, "value-changed", @@ -2727,6 +2742,7 @@ static void objprop_refresh_widget(struct objprop *op, case OPID_CITY_SIZE: case OPID_CITY_SHIELD_STOCK: + case OPID_PLAYER_GOLD: case OPID_GAME_YEAR: spin = objprop_get_child_widget(op, "spin"); if (pv) { @@ -3672,6 +3688,8 @@ static void property_page_setup_objprops(struct property_page *pp) | OPF_HAS_WIDGET | OPF_EDITABLE, VALTYPE_NATION); ADDPROP(OPID_PLAYER_INVENTIONS, _("Inventions"), OPF_IN_LISTVIEW | OPF_HAS_WIDGET | OPF_EDITABLE, VALTYPE_INVENTIONS_ARRAY); +ADDPROP(OPID_PLAYER_GOLD, _("Gold"), OPF_IN_LISTVIEW +| OPF_HAS_WIDGET | OPF_EDITABLE, VALTYPE_INT); break; case OBJTYPE_GAME: diff --git a/server/edithand.c b/server/edithand.c index 46f0612..b80ec90 100644 --- a/server/edithand.c +++ b/server/edithand.c @@ -1012,6 +1012,20 @@ void handle_edit_player(struct connection *pc, update_research = TRUE; } advance_index_iterate_end; + /* Handle a change in the player's gold. */ + if (packet->gold != pplayer->economic.gold) { +if (!(0 <= packet->gold && packet->gold <= 100)) { + notify_conn(pc->self, NULL, E_BAD_COMMAND, + _("Cannot set gold for player %d (%s) because " +"the value %d is outside the allowed range."), + player_number(pplayer), player_name(pplayer), + packet->gold); +} else { + pplayer->economic.gold = packet->gold; + changed = TRUE; +} + } + /* TODO: Handle more property edits. */ ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40666) 2_2 savegame glitch
http://bugs.freeciv.org/Ticket/Display.html?id=40666 > > [markmet...@yahoo.ca - Sat Jan 17 05:32:43 2009]: > > 2_2, At revision 15422. Running under Fedora Core 9 on 32-bit Dell > Optimax or Optima or some such name. > > The popup saying to report the bug wasn't amenable to the normal > Xwindows copy/paste facility so I don't have it in my paste buffer. > Something about '?' and ascii character 63. Confirmed, the server aborts when loading the game: 2: Loading rulesets 0: Detected fatal error in savegame.c line 306: 0: Unknown ascii value for num: '?' 63 civserver: shared.c:772: real_die: Assertion `0' failed. Attached is the full backtrace. --- 私のベッドに横たわっているこのものは何だ。 Using host libthread_db library "/lib/tls/libthread_db.so.1". Core was generated by `/home/book/src/freeciv/freeciv/git-svn/server/civserver'. Program terminated with signal 6, Aborted. #0 0xe410 in __kernel_vsyscall () #0 0xe410 in __kernel_vsyscall () No symbol table info available. #1 0x401aee49 in raise () from /lib/tls/libc.so.6 No symbol table info available. #2 0x401b0872 in abort () from /lib/tls/libc.so.6 No symbol table info available. #3 0x401a8718 in __assert_fail () from /lib/tls/libc.so.6 No symbol table info available. #4 0x08153eb6 in real_die (file=0x81ad2c6 "savegame.c", line=306, format=0x81b0360 "Unknown ascii value for num: '%c' %d") at shared.c:772 __PRETTY_FUNCTION__ = "real_die" #5 0x080c67e0 in player_load_units (plr=0x82d7b6c, plrno=0, file=0xbf87f1b4, savefile_options=0x83e1de0 " attributes client_worklists diplchance_percent embassies improvement_order known32fix map_editor new_owner_map orders resources rulesetdir rulesets spacerace2 startoptions startunits technology_order"..., base_order=0x8bbc1b0) at savegame.c:306 order = (struct unit_order *) 0x83881d8 pbase = orders_buf = 0x85a523c "m" dir_buf = 0x85a5270 "11141" act_buf = 0x85a52ac "?" base_buf = 0x85a52e4 "?" len = 5 pcity = nat_y = type = pbase = punit = (struct unit *) 0x8388118 nat_x = type_name = base = nunits = 18 i = 3 j = 0 activity = #6 0x080cafb7 in game_load_internal (file=0xbf87f1b4) at savegame.c:4642 pplayer = MY_i = loaded_players = 0 i = k = rstate = {v = {110858037, 2888192473, 1139810201, 922988615, 4268674650, 2842322444, 1080591574, 116647236, 1566443572, 357263454, 491471216, 1648595539, 3616012815, 1960519608, 704667697, 1811311063, 180225025, 2000445886, 1599656126, 2490614580, 3396414574, 1728984743, 2859657269, 3512921241, 474990447, 2663290215, 1158859838, 1633866398, 635464404, 3849400742, 1654856301, 2945604131, 2151016655, 2669993821, 1771682283, 520853819, 3175951126, 3171690031, 2141565956, 2136977119, 4228626736, 3977012155, 2178530021, 3660295052, 158459624, 3901430931, 3327550106, 1261799287, 524691850, 1677292037, 2396604893, 18397818, 3382944109, 3759248431, 3775909077, 2928576877}, j = 4, k = 35, x = 3, is_init = true} string = improvement_order_size = 79 technology_order_size = 182 civstyle = improvement_order = (char **) 0x83b4cb0 technology_order = (char **) 0x8412f58 special_order = (enum tile_special_type *) 0x83e1cf0 base_order = (struct base_type **) 0x8bbc1b0 savefile_options = 0x83e1de0 " attributes client_worklists diplchance_percent embassies improvement_order known32fix map_editor new_owner_map orders resources rulesetdir rulesets spacerace2 startoptions startunits technology_order"... #7 0x080cdf35 in game_load (file=0xbf87f1b4) at savegame.c:4050 was_send_city_suppressed = false was_send_tile_suppressed = false #8 0x0805d975 in load_command (caller=0x0, filename=0xbf87f82c "bad", check=false) at stdinhand.c:3454 testfile = "bad.sav.bz2\000\207¿èc\027\b\031\000\000\000±\221\...@èÑ\207¿3Ú\027\b\000\000\000\000è o\b\006\000\000\000\000\000&@\000\000\000\0004Ó\207¿\000Ò\207¿a\213\...@\001\000\000\000\003\000\000\000\000\000\000\000\200\a*@\000Ó\207¿üï)@8Ò\207¿mð\030\b\214Ô\207¿\b²o\bÈÒ\207¿e[\030\b\000\000\000\000tÓ\207¿´Ý\207¿a\213\...@\000\000\000\000\000\0009@ØÒ\207¿(£o\b\000\000\000\000\000\0...@hÒ\207¿(£o\bhÒ\207¿Üw\030\b\000\000\000\000\000\0...@\000\000\000\000\000\0009@\000\000\000\000\000\000&@\000\000\000\000ÄÓ"... exts = {0x81977a5 "sav", 0x8198005 "gz", 0x819800c "bz2", 0x8198001 "sav.gz", 0x8198008 "sav.bz2", 0x0} ext = paths = {0x81cbc96 "", 0x8197ff7 "scenario/", 0x0} path = found = loadtimer = (struct timer *) 0x83b4df8 uloadtimer = (struct timer *) 0x83b47a8 file = {filename = 0x82fb628 "./bad.sav.bz2", num_entries = 14815, sections = 0x
[Freeciv-Dev] (PR#40667) [Patch] Drawing traderoutes as lines on the mapview
http://bugs.freeciv.org/Ticket/Display.html?id=40667 > Attached patch implements traderoute line drawing on the main map view. The code is ported from the warclient project and was originally written by pepeto and myself. This code builds on the traderoute display feature in 40447; it is also controlled by "draw city traderoutes" view option (shortcut ctrl-t). See forum discussion (with screenshots): http://forum.freeciv.org/viewtopic.php?p=22863#22863 --- 駱駝の匂いがします。交易しましょう。 diff --git a/client/mapview_common.c b/client/mapview_common.c index 518b6fd..790d55a 100644 --- a/client/mapview_common.c +++ b/client/mapview_common.c @@ -25,6 +25,7 @@ #include "timing.h" /* common */ +#include "game.h" #include "map.h" #include "unitlist.h" @@ -72,6 +73,15 @@ static void queue_mapview_update(enum update_type update); static void queue_mapview_tile_update(struct tile *ptile, enum tile_update_type type); +/* Helper struct for drawing traderoutes. */ +struct traderoute_line { + int x, y, width, height; +}; + +/* A traderoute line might need to be drawn in two parts. */ +static const int MAX_TRADEROUTE_DRAW_LINES = 2; + + /** Refreshes a single tile on the map canvas. **/ @@ -1078,6 +1088,129 @@ static void put_one_tile(struct canvas *pcanvas, enum mapview_layer layer, } /** + Depending on where ptile1 and ptile2 are on the map canvas, a traderoute + line may need to be drawn as two disjointed line segments. This function + fills the given line array 'lines' with the necessary line segments. + + The return value is the number of line segments that need to be drawn. + + NB: It is assumed ptile1 and ptile2 are already consistently ordered. + NB: 'lines' must be able to hold least MAX_TRADEROUTE_DRAW_LINES + elements. +**/ +static int traderoute_to_canvas_lines(const struct tile *ptile1, + const struct tile *ptile2, + struct traderoute_line *lines) +{ + int dx, dy; + + if (!ptile1 || !ptile2 || !lines) { +return 0; + } + + base_map_distance_vector(&dx, &dy, TILE_XY(ptile1), TILE_XY(ptile2)); + map_to_gui_pos(tileset, &lines[0].width, &lines[0].height, dx, dy); + + /* FIXME: Remove these casts. */ + tile_to_canvas_pos(&lines[0].x, &lines[0].y, (struct tile *)ptile1); + tile_to_canvas_pos(&lines[1].x, &lines[1].y, (struct tile *)ptile2); + + if (lines[1].x - lines[0].x == lines[0].width + && lines[1].y - lines[0].y == lines[0].height) { +return 1; + } + + lines[1].width = -lines[0].width; + lines[1].height = -lines[0].height; + return 2; +} + +/** + Draw a colored traderoute line from one tile to another. +**/ +static void draw_traderoute_line(const struct tile *ptile1, + const struct tile *ptile2, + enum color_std color) +{ + struct traderoute_line lines[MAX_TRADEROUTE_DRAW_LINES]; + int line_count, i; + struct color *pcolor; + + if (!ptile1 || !ptile2) { +return; + } + + pcolor = get_color(tileset, color); + if (!pcolor) { +return; + } + + /* Order the source and destination tiles consistently + * so that if a line is drawn twice it does not produce + * ugly effects due to dashes not lining up. */ + if (tile_index(ptile2) > tile_index(ptile1)) { +const struct tile *tmp; +tmp = ptile1; +ptile1 = ptile2; +ptile2 = tmp; + } + + line_count = traderoute_to_canvas_lines(ptile1, ptile2, lines); + for (i = 0; i < line_count; i++) { +canvas_put_line(mapview.store, pcolor, LINE_BORDER, +lines[i].x + tileset_tile_width(tileset) / 2, +lines[i].y + tileset_tile_height(tileset) / 2, +lines[i].width, lines[i].height); + } +} + +/** + Draw all traderoutes for the given city. +**/ +static void draw_traderoutes_for_city(const struct city *pcity_src) +{ + int i; + const struct city *pcity_dest; + + if (!pcity_src) { +return; + } + + for (i = 0; i < NUM_TRADEROUTES; i++) { +pcity_dest = game_find_city_by_number(pcity_src->trade[i]); +if (!pcity_dest) { + continue; +} +draw_traderoute_line(city_tile(pcity_src), city_tile(pcity_dest), + COLOR_OVERVIEW_LAND); /* Green. */ + } +} + +/***
[Freeciv-Dev] (PR#40668) [Patch] Minimal mapview traderoute lines for 2.1
http://bugs.freeciv.org/Ticket/Display.html?id=40668 > The attached patch implements traderoute line drawing on the main map, toggled by ctrl-t. This is a minimal backport of 40447 + 40667 for S2_1. I know this is a feature rather than a bugfix, but it is fairly often requested by users, and the code is pretty well tested (having been used in warclient for a long time now). Or we can keep the current traderoute interface in 2.1 as is, and have this feature for 2.2 only. --- 俺が雄牛を新しい戦闘機と交換した。 client/control.c | 21 +++ client/control.h |2 + client/gui-gtk-2.0/menu.c |8 +++ client/mapview_common.c | 136 + client/options.c |2 + client/options.h |1 + 6 files changed, 170 insertions(+), 0 deletions(-) diff --git a/client/control.c b/client/control.c index 31a9a09..7f97299 100644 --- a/client/control.c +++ b/client/control.c @@ -1623,6 +1623,19 @@ void request_toggle_city_productions(void) } /** + Toggle display of city traderoutes +**/ +void request_toggle_city_traderoutes(void) +{ + if (!can_client_change_view()) { +return; + } + + draw_city_traderoutes ^= 1; + update_map_canvas_visible(); +} + +/** Toggle display of terrain **/ void request_toggle_terrain(void) @@ -2686,6 +2699,14 @@ void key_city_productions_toggle(void) /** ... **/ +void key_city_traderoutes_toggle(void) +{ + request_toggle_city_traderoutes(); +} + +/** +... +**/ void key_terrain_toggle(void) { request_toggle_terrain(); diff --git a/client/control.h b/client/control.h index 6bdbb27..63b7f0c 100644 --- a/client/control.h +++ b/client/control.h @@ -107,6 +107,7 @@ void request_toggle_map_borders(void); void request_toggle_city_names(void); void request_toggle_city_growth(void); void request_toggle_city_productions(void); +void request_toggle_city_traderoutes(void); void request_toggle_terrain(void); void request_toggle_coastline(void); void request_toggle_roads_rails(void); @@ -151,6 +152,7 @@ void key_center_capital(void); void key_city_names_toggle(void); void key_city_growth_toggle(void); void key_city_productions_toggle(void); +void key_city_traderoutes_toggle(void); void key_terrain_toggle(void); void key_coastline_toggle(void); void key_roads_rails_toggle(void); diff --git a/client/gui-gtk-2.0/menu.c b/client/gui-gtk-2.0/menu.c index 009ec01..ba77872 100644 --- a/client/gui-gtk-2.0/menu.c +++ b/client/gui-gtk-2.0/menu.c @@ -100,6 +100,7 @@ enum MenuID { MENU_VIEW_SHOW_CITY_NAMES, MENU_VIEW_SHOW_CITY_GROWTH_TURNS, MENU_VIEW_SHOW_CITY_PRODUCTIONS, + MENU_VIEW_SHOW_CITY_TRADEROUTES, MENU_VIEW_SHOW_CITY_WORKERS, MENU_VIEW_SHOW_TERRAIN, MENU_VIEW_SHOW_COASTLINE, @@ -329,6 +330,10 @@ static void view_menu_callback(gpointer callback_data, guint callback_action, if (draw_city_productions ^ GTK_CHECK_MENU_ITEM(widget)->active) key_city_productions_toggle(); break; + case MENU_VIEW_SHOW_CITY_TRADEROUTES: +if (draw_city_traderoutes ^ GTK_CHECK_MENU_ITEM(widget)->active) + key_city_traderoutes_toggle(); +break; case MENU_VIEW_SHOW_CITY_WORKERS: key_city_workers(); break; @@ -781,6 +786,8 @@ static GtkItemFactoryEntry menu_items[] = view_menu_callback, MENU_VIEW_SHOW_CITY_GROWTH_TURNS, "" }, { "/" N_("View") "/" N_("City _Productions"), "p", view_menu_callback, MENU_VIEW_SHOW_CITY_PRODUCTIONS, "" }, + { "/" N_("View") "/" N_("City Traderoutes"), "t", + view_menu_callback, MENU_VIEW_SHOW_CITY_TRADEROUTES, "" }, { "/" N_("View") "/" N_("Draw city worker map grid"), "t", view_menu_callback, MENU_VIEW_SHOW_CITY_WORKERS}, { "/" N_("View") "/sep1",NULL, @@ -1325,6 +1332,7 @@ void update_menus(void) menus_set_active("/_View/City G_rowth", draw_city_growth); menus_set_active("/_View/City _Productions", draw_city_productions); +menus_set_active("/_View/City Traderoutes", draw_city_traderoutes); menus_set_active("/_View/Terrain", draw_terrain); menus_set_active("/_View/Coastline", draw_coastline); menus_set_sensitive("/_View/Coastline", !draw_terrain); diff --git a/client/mapview_common.c b/client/mapview_common.c index 0fcff9d..fe10f4d 100644 --- a/client/mapview_common.c +++ b/client/mapview_common.c @@ -23,6 +23,7 @@ #include "support.h" #inc
[Freeciv-Dev] (PR#40671) [Patch] Allow underscore in option names
http://bugs.freeciv.org/Ticket/Display.html?id=40671 > Attached patch allows the underscore character '_' to be used in option names. This is necessary for the prefix "mgr_" which I intend to use for migration related options in 40612. Hopefully I have not missed some bad side-effect about using '_' in option names... --- 下線のある文字を覚えてください。 commit 6ef157a101cec93f90da14b6a49837e5afe8a34d Author: Madeline Book Date: Wed Jan 21 21:13:25 2009 -0500 Allow underscore character '_' in option names. diff --git a/server/stdinhand.c b/server/stdinhand.c index af02e70..38277f8 100644 --- a/server/stdinhand.c +++ b/server/stdinhand.c @@ -1999,7 +1999,7 @@ static bool show_command(struct connection *caller, char *str, bool check) **/ static bool is_ok_opt_name_char(char c) { - return my_isalnum(c); + return my_isalnum(c) || c == '_'; } /** ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40612) Patch: migration
http://bugs.freeciv.org/Ticket/Display.html?id=40612 > I have made some minor changes to the combined v6 patches (the base migration patch v6 and the food patch). The result is the attached patch which could be commited to trunk, if nobody has any objection or problems in the code are found. Migration is a pretty radical game concept and changes the game mechanics substantially. There are similarities between certain aspects of this feature and other civ game rules, for example the "city migration score" is sort of like a city's "culture rating" from civ3; the modular nature of the code in this patch will make future generalizations to features like "culture" possible. The main change from v6 is in the naming of the various migration settings. There is now one master setting 'migration' which controls whether migration is activated in the game. The other settings have no effect if this option is disabled. By default 'migration' is set to 0, i.e. migration is off. The other migration settings are renamed: migrationturn - mgr_turninterval migrationfood - mgr_foodneeded migrationdist - mgr_distance migrationworld - mgr_worldchance migrationplayer - mgr_nationchance This is so that users do not have to type the full "migration" prefix to get an unambiguous match, yet still can see from the name that the setting is migration related. The patch in 40671 is required to make the set command work with option names containing underscores. In anticipation of future use beyond the migration feature, I have made the city "migration score" a field in the city struct, and added this field to the city info packet sent to clients which can see the city internals. However, since at the moment the score is only updated and used in the check_city_migrations() function, and since there would appear to be no secfile functions for float datatypes, I have neglected to save/load this field in savegames. This can be easily added later if needed. As for user visible messages, I have changed the migration messages to give the nation of a city rather than the name of the player that owns it. I have also added TRANS (translator) comments to clarify what the %s formats should be interpreted as. Otherwise I have just normalized and simplified the code in a few places. The logic should be same as in v6. I would appreciate more testing (if you don't mind doing the full re-compile when this patch is applied), especially gameplay with various combinations of the migration settings to determine the best default values. --- 旅は長くて苦しかった。たくさん死んじゃった。 common/city.h |1 + common/game.c |6 + common/game.h | 20 +++ common/packets.def |7 + server/citytools.c |7 +- server/citytools.h |8 +- server/cityturn.c | 397 server/cityturn.h |3 + server/savegame.c | 30 server/settings.c | 78 ++ server/srv_main.c |7 + version.in |2 +- 12 files changed, 559 insertions(+), 7 deletions(-) diff --git a/common/city.h b/common/city.h index 6fef23f..f3f36cf 100644 --- a/common/city.h +++ b/common/city.h @@ -330,6 +330,7 @@ struct city { int steal;/* diplomats steal once; for spies, gets harder */ int turn_founded; int turn_last_built; + float migration_score;/* Updated by check_city_migrations. */ int before_change_shields;/* If changed this turn, shields before penalty */ int caravan_shields; /* If caravan has helped city to build wonder. */ diff --git a/common/game.c b/common/game.c index 25e627f..31c7337 100644 --- a/common/game.c +++ b/common/game.c @@ -275,6 +275,12 @@ void game_init(void) game.info.celebratesize = GAME_DEFAULT_CELEBRATESIZE; game.info.savepalace= GAME_DEFAULT_SAVEPALACE; game.info.natural_city_names = GAME_DEFAULT_NATURALCITYNAMES; + game.info.migration= GAME_DEFAULT_MIGRATION; + game.info.mgr_turninterval = GAME_DEFAULT_MGR_TURNINTERVAL; + game.info.mgr_foodneeded = GAME_DEFAULT_MGR_FOODNEEDED; + game.info.mgr_distance = GAME_DEFAULT_MGR_DISTANCE; + game.info.mgr_worldchance = GAME_DEFAULT_MGR_WORLDCHANCE; + game.info.mgr_nationchance = GAME_DEFAULT_MGR_NATIONCHANCE; game.info.angrycitizen = GAME_DEFAULT_ANGRYCITIZEN; game.info.foodbox = GAME_DEFAULT_FOODBOX; game.info.shieldbox = GAME_DEFAULT_SHIELDBOX; diff --git a/common/game.h b/common/game.h index f993b36..ce4da03 100644 --- a/common/game.h +++ b/common/game.h @@ -250,6 +250,26 @@ bool setting_class_is_changeable(enum sset_class class); #define GAME_DEFAULT_NATURALCITYNAMES TRUE +#define GAME_DEFAULT_MIGRATIONFALSE + +#define GAME_DEFAULT_MGR_TURNINTERVAL 5 +#define GAME_MIN_MGR_TURNINTERVAL 1 +#define GAME_MAX_MGR_TURNINTERVAL 100 + +#define GAME_DEFAULT_MGR_FOODNEEDED TRUE + +#define GAME_DEFAULT_MGR_DISTANCE 3 +#defin
[Freeciv-Dev] (PR#40673) [Patch] List matching names for ambiguous prefixes
http://bugs.freeciv.org/Ticket/Display.html?id=40673 > The attached patch makes the /help command list all matching option or command names when the user uses it on an ambiguous name prefix. For example, from the server console: > help t Help argument 't' is ambiguous. Possible matches: team take timeoutincrease topology tinyisles temperature techlevel techpenalty timeout timeaddenemymove turnblock This is achieved by augmenting the function match_prefix() to take an int array that is filled in with the indices of all of the potential matches. The resulting function is renamed to match_prefix_full() and a convenience wrapper match_prefix() is added so that existing code works without modification. A function cmd_reply_matches() is added to stdinhand.c which takes the array of indices and constructs a simple reply message listing the matched names and sends it to the calling user. --- あいまいさはいとおしい。 server/stdinhand.c | 46 -- utility/shared.c | 41 ++--- utility/shared.h | 10 ++ 3 files changed, 88 insertions(+), 9 deletions(-) diff --git a/server/stdinhand.c b/server/stdinhand.c index af02e70..6930d9c 100644 --- a/server/stdinhand.c +++ b/server/stdinhand.c @@ -4120,6 +4120,44 @@ static void show_help_command_list(struct connection *caller, } /** + Send a reply to the caller listing the matched names from an ambiguous + prefix. +**/ +static void cmd_reply_matches(enum command_id cmd, + struct connection *caller, + m_pre_accessor_fn_t accessor_fn, + int *matches, int num_matches) +{ + char buf[MAX_LEN_MSG]; + const char *src, *end; + char *dest; + int i; + + if (accessor_fn == NULL || matches == NULL || num_matches < 1) { +return; + } + + dest = buf; + end = buf + sizeof(buf) - 1; + + for (i = 0; i < num_matches && dest < end; i++) { +src = accessor_fn(matches[i]); +if (!src) { + continue; +} +if (dest != buf) { + *dest++ = ' '; +} +while (*src != '\0' && dest < end) { + *dest++ = *src++; +} + } + *dest = '\0'; + + cmd_reply(cmd, caller, C_COMMENT, _("Possible matches: %s"), buf); +} + +/** Additional 'help' arguments **/ enum HELP_GENERAL_ARGS { HELP_GENERAL_COMMANDS, HELP_GENERAL_OPTIONS, @@ -4153,14 +4191,16 @@ static const char *helparg_accessor(int i) { **/ static bool show_help(struct connection *caller, char *arg) { + int matches[64], num_matches = 0; enum m_pre_result match_result; int ind; assert(!may_use_nothing(caller)); /* no commands means no help, either */ - match_result = match_prefix(helparg_accessor, HELP_ARG_NUM, 0, - mystrncasecmp, NULL, arg, &ind); + match_result = match_prefix_full(helparg_accessor, HELP_ARG_NUM, 0, + mystrncasecmp, NULL, arg, &ind, matches, + ARRAY_SIZE(matches), &num_matches); if (match_result==M_PRE_EMPTY) { show_help_intro(caller, CMD_HELP); @@ -4169,6 +4209,8 @@ static bool show_help(struct connection *caller, char *arg) if (match_result==M_PRE_AMBIGUOUS) { cmd_reply(CMD_HELP, caller, C_FAIL, _("Help argument '%s' is ambiguous."), arg); +cmd_reply_matches(CMD_HELP, caller, helparg_accessor, + matches, num_matches); return FALSE; } if (match_result==M_PRE_FAIL) { diff --git a/utility/shared.c b/utility/shared.c index dc29a9e..fdb6ef3 100644 --- a/utility/shared.c +++ b/utility/shared.c @@ -1512,20 +1512,41 @@ const char *m_pre_description(enum m_pre_result result) } /*** + See match_prefix_full(). +***/ +enum m_pre_result match_prefix(m_pre_accessor_fn_t accessor_fn, + size_t n_names, + size_t max_len_name, + m_pre_strncmp_fn_t cmp_fn, + m_strlen_fn_t len_fn, + const char *prefix, + int *ind_result) +{ + return match_prefix_full(accessor_fn, n_names, max_len_name, cmp_fn, + len_fn, prefix, ind_result, NULL, 0, NULL); +} + +/*** Given n names, with maximum length max_len_name, accessed by accessor_fn(0
[Freeciv-Dev] (PR#40675) [Patch] Fix city dialog shortcut conflicts
http://bugs.freeciv.org/Ticket/Display.html?id=40675 > Conflicts in the gtk2 city dialog shortcuts were reported by Susanna Björverud on freeciv-i18n. The attached patch fixes all conflicts I could find within the city dialog and its sub-tabs by re-assigning the mnemonic keys. --- 都市には、衝突がよくある。 client/gui-gtk-2.0/citydlg.c |8 client/gui-gtk-2.0/cma_fe.c | 15 +-- client/gui-gtk-2.0/wldlg.c |2 +- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/client/gui-gtk-2.0/citydlg.c b/client/gui-gtk-2.0/citydlg.c index 986a630..071afc9 100644 --- a/client/gui-gtk-2.0/citydlg.c +++ b/client/gui-gtk-2.0/citydlg.c @@ -842,7 +842,7 @@ static void create_and_append_overview_page(struct city_dialog *pdialog) label = g_object_new(GTK_TYPE_LABEL, "use-underline", TRUE, "mnemonic-widget", view, - "label", _("_Improvements:"), + "label", _("I_mprovements:"), "xalign", 0.0, "yalign", 0.5, NULL); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); @@ -901,7 +901,7 @@ target_drag_data_received(GtkWidget *w, GdkDragContext *context, */ static void create_and_append_worklist_page(struct city_dialog *pdialog) { - const char *tab_title = _("_Production"); + const char *tab_title = _("P_roduction"); GtkWidget *label = gtk_label_new_with_mnemonic(tab_title); GtkWidget *page, *hbox, *editor, *bar; @@ -952,7 +952,7 @@ static void create_and_append_worklist_page(struct city_dialog *pdialog) static void create_and_append_happiness_page(struct city_dialog *pdialog) { GtkWidget *page, *vbox, *label, *table, *align; - const char *tab_title = _("_Happiness"); + const char *tab_title = _("Happ_iness"); page = gtk_hbox_new(FALSE, 6); gtk_container_set_border_width(GTK_CONTAINER(page), 8); @@ -1119,7 +1119,7 @@ static void create_and_append_settings_page(struct city_dialog *pdialog) vbox2 = gtk_vbox_new(TRUE, 0); gtk_container_add(GTK_CONTAINER(frame), vbox2); - button = gtk_button_new_with_mnemonic(_("_Rename...")); + button = gtk_button_new_with_mnemonic(_("R_ename...")); pdialog->misc.rename_command = button; gtk_container_add(GTK_CONTAINER(vbox2), button); g_signal_connect(button, "clicked", diff --git a/client/gui-gtk-2.0/cma_fe.c b/client/gui-gtk-2.0/cma_fe.c index 14af71a..9b740c4 100644 --- a/client/gui-gtk-2.0/cma_fe.c +++ b/client/gui-gtk-2.0/cma_fe.c @@ -209,7 +209,7 @@ struct cma_dialog *create_cma_dialog(struct city *pcity) struct cma_dialog *pdialog; struct cm_parameter param; GtkWidget *frame, *page, *hbox, *label, *table; - GtkWidget *vbox, *sw, *hscale, *button, *align; + GtkWidget *vbox, *sw, *hscale, *button, *align, *image; GtkListStore *store; GtkCellRenderer *rend; GtkWidget *view; @@ -268,7 +268,7 @@ struct cma_dialog *create_cma_dialog(struct city *pcity) label = g_object_new(GTK_TYPE_LABEL, "use-underline", TRUE, "mnemonic-widget", view, - "label", _("_Presets:"), + "label", _("Prese_ts:"), "xalign", 0.0, "yalign", 0.5, NULL); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); @@ -284,10 +284,13 @@ struct cma_dialog *create_cma_dialog(struct city *pcity) gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_EDGE); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); - pdialog->add_preset_command = gtk_button_new_from_stock(GTK_STOCK_NEW); - gtk_container_add(GTK_CONTAINER(hbox), pdialog->add_preset_command); - g_signal_connect(pdialog->add_preset_command, "clicked", - G_CALLBACK(cma_add_preset_callback), pdialog); + button = gtk_button_new_with_mnemonic(_("Ne_w")); + image = gtk_image_new_from_stock(GTK_STOCK_NEW, GTK_ICON_SIZE_BUTTON); + gtk_button_set_image(GTK_BUTTON(button), image); + gtk_container_add(GTK_CONTAINER(hbox), button); + g_signal_connect(button, "clicked", + G_CALLBACK(cma_add_preset_callback), pdialog); + pdialog->add_preset_command = button; pdialog->del_preset_command = gtk_button_new_from_stock(GTK_STOCK_DELETE); gtk_container_add(GTK_CONTAINER(hbox), pdialog->del_preset_command); diff --git a/client/gui-gtk-2.0/wldlg.c b/client/gui-gtk-2.0/wldlg.c index d10ca04..8580ca1 100644 --- a/client/gui-gtk-2.0/wldlg.c +++ b/client/gui-gtk-2.0/wldlg.c @@ -1249,7 +1249,7 @@ GtkWidget *create_worklist(void) ptr->help_cmd = button; gtk_widget_set_sensitive(ptr->help_cmd, FALSE); - button = gtk_button_new_with_mnemonic(_("Chan_ge Production")); + button = gtk_button_new_with_mnemonic(_("Change Prod_uction")); gtk_container_add(GTK_CONTAINER(bbox), button); g_signal_connect(button, "clicked", G_CALLBACK(change_callback), ptr); ___ Freeciv-dev mailing
[Freeciv-Dev] (PR#40618) randomize genlist
http://bugs.freeciv.org/Ticket/Display.html?id=40618 > > [matthias.pfaffer...@mapfa.de - Sat Jan 03 12:50:40 2009]: > > Am Saturday 03 January 2009 02:27:31 schrieb Madeline Book: > > http://bugs.freeciv.org/Ticket/Display.html?id=40618 > > > > > > [matthias.pfaffer...@mapfa.de - Fri Jan 02 21:15:47 2009]: > > > > > > This patch adds the possibility to randomize the lists used by > > > freeciv. > > > > I think array_shuffle() would be better placed in utility/ > > shared.[ch], since it is useful for more than just genlists, > > and shared.h already has some array related stuff. > > done > > > Also, it should probably use myrand() from utility/rand.[ch] > > instead of the system rand(). This will make it possible to > > reproduce the same "random" behavior via seed parameters > > (e.g. mapseed, gameseed), which helps in debugging. > > done > > > Lastly, the two "for" lines in genlist_shuffle() are missing > > some spaces. ;) > > done; I just copied the line from the function above ... > > The patch is only compile tested. Attached version 3 just makes some minor style fixes and makes compilation work with --enable-debug. --- おっと。切り直すね。 server/plrhand.c | 18 ++ utility/genlist.c | 34 ++ utility/genlist.h |1 + utility/shared.c | 18 ++ utility/shared.h |3 +++ utility/speclist.h |6 ++ 6 files changed, 72 insertions(+), 8 deletions(-) diff --git a/server/plrhand.c b/server/plrhand.c index 507444a..2aa8f1f 100644 --- a/server/plrhand.c +++ b/server/plrhand.c @@ -1311,22 +1311,24 @@ void maybe_make_contact(struct tile *ptile, struct player *pplayer) **/ void shuffle_players(void) { - int i, pos, tmp; + /* shuffled_order is defined global */ + int n = player_slot_count(); + int i; freelog(LOG_DEBUG, "shuffle_players: creating shuffled order"); - for (i = 0; i < player_slot_count(); i++) { + for (i = 0; i < n; i++) { shuffled_order[i] = i; } - for (i = 0; i < player_slot_count() - 1; i++) { -/* for each run: shuffled[ dataptr = sortbuf[i]; } } + +/ + Randomize the elements of a genlist using the Fisher-Yates shuffle. + + see: genlist_sort() and shared.c:array_shuffle() +/ +void genlist_shuffle(struct genlist *pgenlist) +{ + const int n = genlist_size(pgenlist); + void *sortbuf[n]; + struct genlist_link *myiter; + int i, shuffle[n]; + + if (n <= 1) { +return; + } + + myiter = find_genlist_position(pgenlist, 0); + for (i = 0; i < n; i++, ITERATOR_NEXT(myiter)) { +sortbuf[i] = ITERATOR_PTR(myiter); +/* also create the shuffle list */ +shuffle[i] = i; + } + + /* randomize it */ + array_shuffle(shuffle, n); + + /* create the shuffled list */ + myiter = find_genlist_position(pgenlist, 0); + for (i = 0; i < n; i++, ITERATOR_NEXT(myiter)) { +myiter->dataptr = sortbuf[shuffle[i]]; + } +} diff --git a/utility/genlist.h b/utility/genlist.h index 7090b00..415c699 100644 --- a/utility/genlist.h +++ b/utility/genlist.h @@ -84,6 +84,7 @@ bool genlist_search(struct genlist *pgenlist, const void *data); void genlist_sort(struct genlist *pgenlist, int (*compar)(const void *, const void *)); +void genlist_shuffle(struct genlist *pgenlist); #define ITERATOR_PTR(iter) ((iter) ? ((iter)->dataptr) : NULL) #define ITERATOR_NEXT(iter) (iter = (iter)->next) diff --git a/utility/shared.c b/utility/shared.c index dc29a9e..9abccca 100644 --- a/utility/shared.c +++ b/utility/shared.c @@ -1797,3 +1797,21 @@ char scanin(char **buf, char *delimiters, char *dest, int size) return found; } + +/ + Randomize the elements of an array using the Fisher-Yates shuffle. + + see: http://benpfaff.org/writings/clc/shuffle.html +/ +void array_shuffle(int *array, int n) +{ + if (n > 1 && array != NULL) { +int i, j, t; +for (i = 0; i < n - 1; i++) { + j = i + myrand(n - i); + t = array[j]; + array[j] = array[i]; + array[i] = t; +} + } +} diff --git a/utility/shared.h b/utility/shared.h index df20992..eada885 100644 --- a/utility/shared.h +++ b/utility/shared.h @@ -244,4 +244,7 @@ bool make_dir(const char *pathname); bool path_is_absolute(const char *filename); char scanin(char **buf, char *delimiters, char *dest, int size); + +void array_shuffle(int *array, int n); + #endif /* FC__S
[Freeciv-Dev] (PR#40676) crash: Assertion `*connect_initial == 0' failed
http://bugs.freeciv.org/Ticket/Display.html?id=40676 > > [...@domaintje.com - Sat Jan 24 18:48:35 2009]: > > Freeciv crashed with the following error: > >civclient: goto.c:767: fill_client_goto_parameter: Assertion > `*connect_initial == 0' failed. > > [...] > > I have been able to replicate this crash three times using a saved > game, > which I will attach once a ticket has been created. To replicate the > crash: >1. Start the game as the Viking player >2. Select the worker located directly south of Ribe >3. Hit control-shift-i > > A backtrace is attached. Thanks for the report. I have confirmed the crash when using ctrl-shift-i (connect irrigation) with a worker initially on a tile with a mine. The attached patch "fixes" the assertion failure, though I am not sure how correct it is. For example despite the fact that get_activity_time() is trying to indicate that mines should not be removed by the connection, with this patch the client will happily connect over a mine (removing it in the process). It's hard for me to follow what the changes in 18010 (where this code was first introduced) are trying to do; I'll think about it more, or hopefully some- one more versed in this part of the codebase will give a hint as to a more correct solution. --- まず鉱山で働かせた。それから畑で働かせた。 diff --git a/client/goto.c b/client/goto.c index 240e76a..fd4342b 100644 --- a/client/goto.c +++ b/client/goto.c @@ -764,7 +764,7 @@ static void fill_client_goto_parameter(struct unit *punit, } } else { /* otherwise moves_left_initially = punit->moves_left (default) */ - assert(*connect_initial == 0); + *connect_initial = 0; } break; case HOVER_NUKE: ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] [RFC] S2_1 multiplayer usability features
I have been trying the 2.1 client (r15425) in multiplayer games as well as talking with players and reading forum postings, and I have to agree that the client is hard (if not impossible) to use to play well. There are a number of annoying behaviours that constantly get in the way, taking away time and enjoyment needlessly. (See for example: http://forum.freeciv.org/viewtopic.php?t=5756 ) The server also poorly supports multiplayer games, making it hard for players to organize games fairly and efficiently. Although I seem to recall the "policy" that no new features be allowed into the 2.1 branch (only bugfixes), I would propose that basic usability features that have been tried, tested and found to be good in warclient/warserver be allowed to be ported and integrated into the S2_1 branch. This is in preference to having a "2.1 warclient" of custom player patches so we don't repeat the annoying "fork" situation as happened with 2.0. Of course I will submit each feature in its own ticket, and if the code is found to be dubious or the change undesirable we can omit it or postpone it until 2.2. I would hope that in 3-4 weeks we can release 2.1.9 and it would be close to as playable as warclient is on 2.0. --- 勘弁してくれ! ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40677) [Patch] S2_1 city report governor menu
http://bugs.freeciv.org/Ticket/Display.html?id=40677 > This is the S2_1 port of 40621, and is part of the "basic usability features" for multiplayer 2.1 games. The patch moves the city report governor menu to its own city report toplevel menu entry for ease of accessibility. --- 砲撃は始まります。 diff --git a/client/gui-gtk-2.0/cityrep.c b/client/gui-gtk-2.0/cityrep.c index fef2336..99eb2ee 100644 --- a/client/gui-gtk-2.0/cityrep.c +++ b/client/gui-gtk-2.0/cityrep.c @@ -95,15 +95,17 @@ static void popup_last_menu(GtkMenuShell *menu, gpointer data); static void popup_first_menu(GtkMenuShell *menu, gpointer data); static void popup_next_menu(GtkMenuShell *menu, gpointer data); -static GtkWidget *city_center_command, *city_popup_command, *city_buy_command; +static GtkWidget *city_center_command; +static GtkWidget *city_popup_command; +static GtkWidget *city_buy_command; static GtkWidget *city_production_command; +static GtkWidget *city_governor_command; static GtkWidget *city_total_buy_cost_label; static GtkWidget *change_improvements_item; static GtkWidget *change_units_item; static GtkWidget *change_wonders_item; -static GtkWidget *change_cma_item; static GtkWidget *last_improvements_item; static GtkWidget *last_units_item; @@ -542,6 +544,11 @@ static void append_cma_to_menu_item(GtkMenuItem *parent_item, bool change_cma) struct cm_parameter parameter; GtkWidget *w; + w = gtk_menu_item_get_submenu(parent_item); + if (w != NULL && GTK_WIDGET_VISIBLE(w)) { +return; + } + gtk_menu_item_remove_submenu(parent_item); if (!can_client_issue_orders()) { return; @@ -712,6 +719,11 @@ static GtkWidget *create_city_report_menubar(void) gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); create_last_menu(item); + item = gtk_menu_item_new_with_mnemonic(_("Gover_nor")); + city_governor_command = item; + gtk_menu_shell_append(GTK_MENU_SHELL(menubar), item); + append_cma_to_menu_item(GTK_MENU_ITEM(item), TRUE); + item = gtk_menu_item_new_with_mnemonic(_("_Select")); gtk_menu_shell_append(GTK_MENU_SHELL(menubar), item); create_select_menu(item); @@ -1173,6 +1185,10 @@ void city_report_dialog_update(void) city_selection_changed_callback(city_selection); +if (GTK_WIDGET_SENSITIVE(city_governor_command)) { + append_cma_to_menu_item(GTK_MENU_ITEM(city_governor_command), TRUE); +} + select_menu_cached = FALSE; } } @@ -1228,8 +1244,6 @@ static void create_change_menu(GtkWidget *item) gtk_menu_shell_append(GTK_MENU_SHELL(menu), change_improvements_item); change_wonders_item = gtk_menu_item_new_with_label(_("Wonders")); gtk_menu_shell_append(GTK_MENU_SHELL(menu), change_wonders_item); - change_cma_item = gtk_menu_item_new_with_label(_("Citizen Governor")); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), change_cma_item); } / @@ -1312,7 +1326,6 @@ static void popup_change_menu(GtkMenuShell *menu, gpointer data) FALSE, TRUE, CO_CHANGE, city_can_build_impr_or_unit, G_CALLBACK(select_impr_or_unit_callback), n); - append_cma_to_menu_item(GTK_MENU_ITEM(change_cma_item), TRUE); } / @@ -1588,6 +1601,7 @@ static void city_selection_changed_callback(GtkTreeSelection *selection) if (n == 0) { gtk_widget_set_sensitive(city_production_command, FALSE); +gtk_widget_set_sensitive(city_governor_command, FALSE); gtk_widget_set_sensitive(city_center_command, FALSE); gtk_widget_set_sensitive(city_popup_command, FALSE); gtk_widget_set_sensitive(city_buy_command, FALSE); @@ -1601,6 +1615,8 @@ static void city_selection_changed_callback(GtkTreeSelection *selection) gtk_widget_set_sensitive(city_production_command, can_client_issue_orders()); +gtk_widget_set_sensitive(city_governor_command, + can_client_issue_orders()); gtk_widget_set_sensitive(city_center_command, TRUE); gtk_widget_set_sensitive(city_popup_command, TRUE); gtk_widget_set_sensitive(city_buy_command, can_client_issue_orders()); ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40678) [Patch] Option to disable mouse cursor changing
http://bugs.freeciv.org/Ticket/Display.html?id=40678 > The mouse cursor changing code is unreliable to the point of being a constant annoyance when playing a game, doubly so in multiplayer time contraints. Numerous people have complained about this: http://bugs.freeciv.org/Ticket/Display.html?id=40306 http://bugs.freeciv.org/Ticket/Display.html?id=39800 http://forum.freeciv.org/viewtopic.php?p=22936#22936 and I agree. Until I or someone has the time to give it a thorough examining, here is a patch that implements an option to turn off the cursor changing feature (default enabled, that is, the default setting preserves the current behaviour). --- 私は地下室に隠れています。 client/control.c |4 client/options.c |7 +++ client/options.h |1 + 3 files changed, 12 insertions(+), 0 deletions(-) diff --git a/client/control.c b/client/control.c index 31a9a09..0856d93 100644 --- a/client/control.c +++ b/client/control.c @@ -931,6 +931,10 @@ void control_mouse_cursor(struct tile *ptile) struct city *pcity = NULL; struct unit_list *active_units = get_units_in_focus(); + if (!enable_cursor_changes) { +return; + } + if (C_S_RUNNING != client_state()) { action_state = CURSOR_ACTION_DEFAULT; return; diff --git a/client/options.c b/client/options.c index f72717b..a7cfd44 100644 --- a/client/options.c +++ b/client/options.c @@ -87,6 +87,7 @@ bool ask_city_name = TRUE; bool popup_new_cities = TRUE; bool keyboardless_goto = TRUE; bool show_task_icons = TRUE; +bool enable_cursor_changes = TRUE; /* This option is currently set by the client - not by the user. */ bool update_city_text_in_refresh_tile = TRUE; @@ -243,6 +244,12 @@ static client_option common_options[] = { N_("Setting this option will pop up a newly-founded " "city's city dialog automatically."), COC_INTERFACE), + GEN_BOOL_OPTION(enable_cursor_changes, N_("Enable cursor changing"), + N_("This option controls whether the client should " + "try to change the mouse cursor depending on what " + "is being pointed at, as well as to indicate " + "changes in the client or server state."), + COC_INTERFACE), GEN_BOOL_OPTION(overview.layers[OLAYER_BACKGROUND], N_("Background layer"), diff --git a/client/options.h b/client/options.h index 31268ea..49fdced 100644 --- a/client/options.h +++ b/client/options.h @@ -51,6 +51,7 @@ extern bool popup_new_cities; extern bool update_city_text_in_refresh_tile; extern bool keyboardless_goto; extern bool show_task_icons; +extern bool enable_cursor_changes; enum client_option_type { COT_BOOL, ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40679) [Patch] Re-enable production clipboard copy
http://bugs.freeciv.org/Ticket/Display.html?id=40679 > Somehow it became impossible to copy production to the clipboard using the gtk2 client. This patch re-enables that feature; the mouse key sequences are: shift + ctrl + rmb: Paste production. shift + rmb: Copy production. In trunk the former sequence is used to toggle worker overlays; it is changed to shift + alt + rmb. --- 長い間いる必要になるなら、食物は足りますか。 diff --git a/client/gui-gtk-2.0/mapctrl.c b/client/gui-gtk-2.0/mapctrl.c index 150fe1f..2d1414b 100644 --- a/client/gui-gtk-2.0/mapctrl.c +++ b/client/gui-gtk-2.0/mapctrl.c @@ -290,15 +290,20 @@ gboolean butt_down_mapcanvas(GtkWidget *w, GdkEventButton *ev, gpointer data) case 3: /* RIGHT mouse button */ -/* + RMB : Quickselect a land unit. */ -if (ev->state & GDK_CONTROL_MASK) { - action_button_pressed(ev->x, ev->y, SELECT_LAND); -} -/* + RMB: Paste Production. */ -else if ((ev->state & GDK_SHIFT_MASK) && pcity) { +/* + RMB: Paste Production. */ +if ((ev->state & GDK_SHIFT_MASK) && (ev->state & GDK_CONTROL_MASK) +&& pcity != NULL) { clipboard_paste_production(pcity); cancel_tile_hiliting(); } +/* + RMB: Copy Production. */ +else if (ev->state & GDK_SHIFT_MASK) { + clipboard_copy_production(ptile); +} +/* + RMB : Quickselect a land unit. */ +else if (ev->state & GDK_CONTROL_MASK) { + action_button_pressed(ev->x, ev->y, SELECT_LAND); +} /* Plain RMB click. */ else { /* A foolproof user will depress button on canvas, diff --git a/client/gui-gtk-2.0/mapctrl.c b/client/gui-gtk-2.0/mapctrl.c index d87cc54..f2ffeb6 100644 --- a/client/gui-gtk-2.0/mapctrl.c +++ b/client/gui-gtk-2.0/mapctrl.c @@ -301,23 +301,25 @@ gboolean butt_down_mapcanvas(GtkWidget *w, GdkEventButton *ev, gpointer data) case 3: /* RIGHT mouse button */ -/* + + RMB : Show/hide workers. */ -if ((ev->state & GDK_SHIFT_MASK) && (ev->state & GDK_CONTROL_MASK)) { - if (NULL != pcity) { -overlay_workers_at_city(); - } +/* + + RMB : Show/hide workers. */ +if ((ev->state & GDK_SHIFT_MASK) && (ev->state & GDK_MOD1_MASK) +&& pcity != NULL) { + overlay_workers_at_city(); +} +/* + RMB: Paste Production. */ +else if ((ev->state & GDK_SHIFT_MASK) && (ev->state & GDK_CONTROL_MASK) + && pcity != NULL) { + clipboard_paste_production(pcity); + cancel_tile_hiliting(); +} +/* + RMB: Copy Production. */ +else if (ev->state & GDK_SHIFT_MASK) { + clipboard_copy_production(ptile); } /* + RMB : Quickselect a land unit. */ else if (ev->state & GDK_CONTROL_MASK) { action_button_pressed(ev->x, ev->y, SELECT_LAND); } -/* + RMB: Paste Production. */ -else if ((ev->state & GDK_SHIFT_MASK)) { - if (NULL != pcity) { -clipboard_paste_production(pcity); -cancel_tile_hiliting(); - } -} /* Plain RMB click. */ else { /* A foolproof user will depress button on canvas, ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40680) [Patch] Revert city report column ordering changes
http://bugs.freeciv.org/Ticket/Display.html?id=40680 > The order of city report columns was changed for no good reason as a bundled "feature" of r12989 (39385, not even part of the original ticket request?!). This patch changes the ordering back so that concise rapture/disorder, city name, and city size are again back as the first 3 columns. --- あいつを殺す可能性があります。 diff --git a/client/cityrepdata.c b/client/cityrepdata.c index 5d923c8..bbaaa8d 100644 --- a/client/cityrepdata.c +++ b/client/cityrepdata.c @@ -443,17 +443,22 @@ static const char *cr_entry_cma(const struct city *pcity, #define FUNC_TAG(var) cr_entry_##var, #var static const struct city_report_spec base_city_report_specs[] = { + { FALSE, 1, 1, NULL, NULL, N_("Concise + Rapture, - Disorder"), +NULL, FUNC_TAG(hstate_concise) }, + { TRUE, -15, 0, NULL, N_("?city:Name"), N_("City Name"), +NULL, FUNC_TAG(cityname) }, + { TRUE, 2, 1, NULL, N_("?size [short]:Sz"), N_("Size"), +NULL, FUNC_TAG(size) }, + + { TRUE, -8, 1, NULL, N_("State"), N_("Rapture/Peace/Disorder"), +NULL, FUNC_TAG(hstate_verbose) }, + /* Specialists grouped with init_city_report_game_data specialists */ { FALSE, 7, 1, N_("Special"), N_("?entertainers/scientists/taxmen:E/S/T"), N_("Entertainers, Scientists, Taxmen"), NULL, FUNC_TAG(specialists) }, - { FALSE, 1, 1, NULL, NULL, N_("Concise + Rapture, - Disorder"), -NULL, FUNC_TAG(hstate_concise) }, - { TRUE, -8, 1, NULL, N_("State"), N_("Rapture/Peace/Disorder"), -NULL, FUNC_TAG(hstate_verbose) }, - { FALSE, 2, 1, NULL, N_("?Happy workers:H"), N_("Workers: Happy"), NULL, FUNC_TAG(happy) }, { FALSE, 2, 1, NULL, N_("?Content workers:C"), N_("Workers: Content"), @@ -485,12 +490,6 @@ static const struct city_report_spec base_city_report_specs[] = { N_("?Stock/Target:(Have/Need)"), N_("Turns until growth/famine"), NULL, FUNC_TAG(growturns) }, - { TRUE, 2, 1, NULL, N_("?size [short]:Sz"), N_("Size"), -NULL, FUNC_TAG(size) }, - - /* city name closer to center, try to keep within scroll window */ - { TRUE, -15, 0, NULL, N_("?city:Name"), N_("City Name"), -NULL, FUNC_TAG(cityname) }, { TRUE, 10, 1, N_("Surplus"), N_("?food/production/trade:F/P/T"), N_("Surplus: Food, Production, Trade"), ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40681) [Patch] Include turn number in generated save name
http://bugs.freeciv.org/Ticket/Display.html?id=40681 > The attached patch factors out duplicate save name generating code into a new function generate_save_name(). This function also adds the current turn number to savefile names it generates, so that save files become: _T_.sav.gz e.g. "civgame_T001_-3950.sav.gz". Requested in the forums: http://forum.freeciv.org/viewtopic.php?p=23039#23039 --- どのやり方が一番いいですか?靴下で? diff --git a/server/settings.c b/server/settings.c index f13b13b..32c9224 100644 --- a/server/settings.c +++ b/server/settings.c @@ -1014,7 +1014,7 @@ struct settings_s settings[] = { SSET_META, SSET_INTERNAL, SSET_VITAL, SSET_SERVER_ONLY, N_("Auto-save name prefix"), N_("Automatically saved games will have name " - "\".sav\". This setting sets " + "\"_T_.sav\". This setting sets " "the part."), NULL, GAME_DEFAULT_SAVE_NAME) diff --git a/server/srv_main.c b/server/srv_main.c index b386a40..f7dcef7 100644 --- a/server/srv_main.c +++ b/server/srv_main.c @@ -866,6 +866,30 @@ static void end_turn(void) } /** + Generate a default save file name and place it in the provided buffer. + The name will be of the form "_T_" where: + + = game.save_name + = game.info.turn (zero padded to 3 places) + = game.info.year (zero padded to 5 places with 1 sign character) + = "m" (for "manual save") if 'is_auto_save' is FALSE + + Returns the number of characters written, or the number of characters + that would have been written if truncation occurs. +**/ +static int generate_save_name(char *buf, int buflen, bool is_auto_save) +{ + int nb; + + /* NB: If you change the format here, be sure to update the above + * function comment and the help text for the savegame setting. */ + nb = my_snprintf(buf, buflen, "%s_T%03d_%+05d%s", + game.save_name, game.info.turn, game.info.year, + is_auto_save ? "" : "m"); + return nb; +} + +/** Unconditionally save the game, with specified filename. Always prints a message: either save ok, or failed. @@ -890,10 +914,9 @@ void save_game(char *orig_filename, const char *save_reason) *dot = '\0'; } - /* If orig_filename is NULL or empty, use "civgame.info.year>m". */ + /* If orig_filename is NULL or empty, use a generated default name. */ if (filename[0] == '\0'){ -my_snprintf(filename, sizeof(filename), - "%s%+05dm", game.save_name, game.info.year); +generate_save_name(filename, sizeof(filename), FALSE); } timer_cpu = new_timer_start(TIMER_CPU, TIMER_ACTIVE); @@ -947,8 +970,7 @@ void save_game_auto(const char *save_reason) assert(strlen(game.save_name)<256); - my_snprintf(filename, sizeof(filename), - "%s%+05d.sav", game.save_name, game.info.year); + generate_save_name(filename, sizeof(filename), TRUE); save_game(filename, save_reason); save_ppm(); } ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40658) [Patch] No teleporting to resolve stacks
http://bugs.freeciv.org/Ticket/Display.html?id=40658 > > [book - Mon Jan 12 01:51:02 2009]: > > The attached patch changes the function bounce_unit() to move a > unit to a random tile a maximum of two tiles away from its > current position, chosen from a list of tiles where the unit > can survive (can_unit_survive_at_tile()) and that is not > currently occupied by a non-ally unit or city. If no such tiles > exist, then the unit is disbanded. Version 2 adds a clarifying comment for the 'tiles' array declaration and TRANS comments for the somewhat vague notify messages. --- 私の大切な靴下を絶対に譲れません! diff --git a/server/unittools.c b/server/unittools.c index 8576975..d485f81 100644 --- a/server/unittools.c +++ b/server/unittools.c @@ -1143,25 +1143,61 @@ bool teleport_unit_to_city(struct unit *punit, struct city *pcity, } /** - Teleport or remove a unit due to stack conflict. + Move or remove a unit due to stack conflicts. This function will try to + find a random safe tile within a two tile distance of the unit's current + tile and move the unit there. If no tiles are found, the unit is + disbanded. If 'verbose' is TRUE, a message is sent to the unit owner + regarding what happened. **/ void bounce_unit(struct unit *punit, bool verbose) { - struct player *pplayer = unit_owner(punit); - struct city *pcity = find_closest_owned_city(pplayer, punit->tile, - is_sailing_unit(punit), NULL); + struct player *pplayer; + struct tile *punit_tile; + int count = 0; + + /* I assume that there are no topologies that have more than + * (2d + 1)^2 tiles in the "square" of "radius" d. */ + const int DIST = 2; + struct tile *tiles[(2 * DIST + 1) * (2 * DIST + 1)]; + + if (!punit) { +return; + } + + pplayer = unit_owner(punit); + punit_tile = unit_tile(punit); + + square_iterate(punit_tile, DIST, ptile) { +if (count >= ARRAY_SIZE(tiles)) { + break; +} +if (can_unit_survive_at_tile(punit, ptile) +&& !is_non_allied_city_tile(ptile, pplayer) +&& !is_non_allied_unit_tile(ptile, pplayer)) { + tiles[count++] = ptile; +} + } square_iterate_end; + + if (count > 0) { +struct tile *ptile = tiles[myrand(count)]; - if (pcity && can_unit_exist_at_tile(punit, pcity->tile)) { -(void) teleport_unit_to_city(punit, pcity, 0, verbose); - } else { -/* remove it */ if (verbose) { - notify_player(unit_owner(punit), punit->tile, E_UNIT_LOST_MISC, - _("Disbanded your %s."), - unit_name_translation(punit)); + /* TRANS: A unit is moved to resolve stack conflicts. */ + notify_player(pplayer, ptile, E_UNIT_RELOCATED, _("Moved your %s."), +unit_name_translation(punit)); } -wipe_unit(punit); +move_unit(punit, ptile, 0); +return; + } + + /* Didn't find a place to bounce the unit, just disband it. */ + if (verbose) { +/* TRANS: A unit is disbanded to resolve stack conflicts. */ +notify_player(pplayer, punit_tile, E_UNIT_LOST_MISC, + _("Disbanded your %s."), + unit_name_translation(punit)); } + wipe_unit(punit); } diff --git a/server/unittools.c b/server/unittools.c index 455a9bb..3f3e27f 100644 --- a/server/unittools.c +++ b/server/unittools.c @@ -1024,25 +1024,61 @@ bool teleport_unit_to_city(struct unit *punit, struct city *pcity, } /** - Teleport or remove a unit due to stack conflict. + Move or remove a unit due to stack conflicts. This function will try to + find a random safe tile within a two tile distance of the unit's current + tile and move the unit there. If no tiles are found, the unit is + disbanded. If 'verbose' is TRUE, a message is sent to the unit owner + regarding what happened. **/ void bounce_unit(struct unit *punit, bool verbose) { - struct player *pplayer = unit_owner(punit); - struct city *pcity = find_closest_owned_city(pplayer, punit->tile, - is_sailing_unit(punit), NULL); + struct player *pplayer; + struct tile *punit_tile; + int count = 0; + + /* I assume that there are no topologies that have more than + * (2d + 1)^2 tiles in the "square" of "radius" d. */ + const int DIST = 2; + struct tile *tiles[(2 * DIST + 1) * (2 * DIST + 1)]; + + if (!punit) { +return; + } + + pplayer = unit_owner(punit); + punit_tile = punit->tile; + + square_iterate(punit_tile, DIST, ptile) { +if (count >= ARRAY_SIZE(tiles)) { + break; +} +if (can_unit_survive_at_tile(punit, ptile) +&& !is_non_allied_city_tile(ptile, pplayer) +&& !is_non_all
[Freeciv-Dev] (PR#40681) [Patch] Include turn number in generated save name
http://bugs.freeciv.org/Ticket/Display.html?id=40681 > > [dmarks - Tue Jan 27 00:38:35 2009]: > > How about a prefix for the year part too? > > _T_Y.sav.gz Ok. On second look the underscores do seem uglier than dashes, so I also changed the format to: -T-Y.sav.gz with 'year' being unsigned. So for example: civgame-T001-Y3950BC.sav.gz Or maybe now the 'Y' is unneeded? Probably in the near future someone will just have to make the 'savename' setting a fully printf-style format string encompassing the entire generated name... :| --- この状況では洗濯できませんよ。 diff --git a/server/settings.c b/server/settings.c index f13b13b..2713bda 100644 --- a/server/settings.c +++ b/server/settings.c @@ -1014,7 +1014,7 @@ struct settings_s settings[] = { SSET_META, SSET_INTERNAL, SSET_VITAL, SSET_SERVER_ONLY, N_("Auto-save name prefix"), N_("Automatically saved games will have name " - "\".sav\". This setting sets " + "\"-T-Y.sav\". This setting sets " "the part."), NULL, GAME_DEFAULT_SAVE_NAME) diff --git a/server/srv_main.c b/server/srv_main.c index b386a40..d986dbc 100644 --- a/server/srv_main.c +++ b/server/srv_main.c @@ -866,6 +866,40 @@ static void end_turn(void) } /** + Generate a default save file name and place it in the provided buffer. + The name will be of the form "-T-Y" where: + + = game.save_name + = game.info.turn (zero padded to 3 places) + = game.info.year (not padded and no sign) + = "BC" or "AD" for negative or positive year resp. + = "m" (for "manual save") if 'is_auto_save' is FALSE + + Returns the number of characters written, or the number of characters + that would have been written if truncation occurs. +**/ +static int generate_save_name(char *buf, int buflen, bool is_auto_save) +{ + int nb, year; + const char *year_suffix; + + if (game.info.year < 0) { +year = -game.info.year; +year_suffix = "BC"; + } else { +year = game.info.year; +year_suffix = "AD"; + } + + /* NB: If you change the format here, be sure to update the above + * function comment and the help text for the savegame setting. */ + nb = my_snprintf(buf, buflen, "%s-T%03d-Y%d%s%s", + game.save_name, game.info.turn, year, + year_suffix, is_auto_save ? "" : "m"); + return nb; +} + +/** Unconditionally save the game, with specified filename. Always prints a message: either save ok, or failed. @@ -890,10 +924,9 @@ void save_game(char *orig_filename, const char *save_reason) *dot = '\0'; } - /* If orig_filename is NULL or empty, use "civgame.info.year>m". */ + /* If orig_filename is NULL or empty, use a generated default name. */ if (filename[0] == '\0'){ -my_snprintf(filename, sizeof(filename), - "%s%+05dm", game.save_name, game.info.year); +generate_save_name(filename, sizeof(filename), FALSE); } timer_cpu = new_timer_start(TIMER_CPU, TIMER_ACTIVE); @@ -947,8 +980,7 @@ void save_game_auto(const char *save_reason) assert(strlen(game.save_name)<256); - my_snprintf(filename, sizeof(filename), - "%s%+05d.sav", game.save_name, game.info.year); + generate_save_name(filename, sizeof(filename), TRUE); save_game(filename, save_reason); save_ppm(); } ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40684) [Patch] (i18n) Fix "Workers" translation ambiguity
http://bugs.freeciv.org/Ticket/Display.html?id=40684 > As reported on freeciv-i18n, there were a few unqualified uses of _("Workers") in various places. The attached patch adds either ?city: or ?unit: as appropriate. --- 私は王なら、労働者にさえ綺麗な靴下が与えられます。 commit 2cb408bb4abb75d20fa8705bb3b4370f927619ff Author: Madeline Book Date: Tue Jan 27 15:41:32 2009 -0500 Fix "Workers" translation ambiguity. Reported by: Sini Ruohomaa Susanna Björverud --- client/cityrepdata.c |2 +- client/gui-xaw/citydlg.c |6 +- data/default/units.ruleset |2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/client/cityrepdata.c b/client/cityrepdata.c index 5d923c8..95df7de 100644 --- a/client/cityrepdata.c +++ b/client/cityrepdata.c @@ -462,7 +462,7 @@ static const struct city_report_spec base_city_report_specs[] = { NULL, FUNC_TAG(unhappy) }, { FALSE, 2, 1, NULL, N_("?Angry workers:A"), N_("Workers: Angry"), NULL, FUNC_TAG(angry) }, - { TRUE, 10, 1, N_("Workers"), + { TRUE, 10, 1, N_("?city:Workers"), N_("?happy/content/unhappy/angry:H/C/U/A"), N_("Workers: Happy, Content, Unhappy, Angry"), NULL, FUNC_TAG(workers) }, diff --git a/client/gui-xaw/citydlg.c b/client/gui-xaw/citydlg.c index bc1a864..9fd43bf 100644 --- a/client/gui-xaw/citydlg.c +++ b/client/gui-xaw/citydlg.c @@ -2398,7 +2398,11 @@ void cityopt_cancel_command_callback(Widget w, XtPointer client_data, void cityopt_newcit_triggle_callback(Widget w, XtPointer client_data, XtPointer call_data); -char *newcitizen_labels[] = { N_("Workers"), N_("Scientists"), N_("Taxmen") }; +char *newcitizen_labels[] = { + N_("?city:Workers"), + N_("Scientists"), + N_("Taxmen") +}; static Widget cityopt_shell = 0; static Widget cityopt_triggle; diff --git a/data/default/units.ruleset b/data/default/units.ruleset index 3737f67..4c62553 100644 --- a/data/default/units.ruleset +++ b/data/default/units.ruleset @@ -235,7 +235,7 @@ Settlers and Engineers may work together to decrease the amount of\ ") [unit_worker] -name = _("Workers") +name = _("?unit:Workers") class = "Land" tech_req = "Pottery" obsolete_by = "Engineers" ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40685) [Patch] (i18n) Fix sentence fragments in text_happiness_units
http://bugs.freeciv.org/Ticket/Display.html?id=40685 > Attached patch rephrases explanatory text in the function text_happiness_units() for clarity and to avoid difficult to translate sentence fragments. --- 粉々になりたくない! commit 673b33072d0bb02c7c0202c2bd0ff4c620b726b0 Author: Madeline Book Date: Tue Jan 27 15:46:20 2009 -0500 Fix sentence fragments. Reported by: Sini Ruohomaa --- client/text.c | 27 ++- 1 files changed, 10 insertions(+), 17 deletions(-) diff --git a/client/text.c b/client/text.c index 9295f14..8f555f1 100644 --- a/client/text.c +++ b/client/text.c @@ -1263,7 +1263,6 @@ const char *text_happiness_cities(const struct city *pcity) / Describing units that affect happiness. - FIXME: sentence fragments with parenthesis are hard to translate! / const char *text_happiness_units(const struct city *pcity) { @@ -1274,25 +1273,19 @@ const char *text_happiness_units(const struct city *pcity) astr_clear(&str); if (mlmax > 0) { -astr_add_line(&str, - /* TRANS: Martial law opening parenthesis */ - _("Martial law in effect (")); - +int mleach = get_city_bonus(pcity, EFT_MARTIAL_LAW_EACH); if (mlmax == 100) { - astr_add(&str, - /* TRANS: no [unit] maximum */ - _("no maximum, ")); + astr_add_line(&str, "%s", _("Unlimited martial law in effect.")); } else { - astr_add(&str, - PL_("%d unit maximum, ", - "%d units maximum, ", - mlmax), - mlmax); + astr_add_line(&str, PL_("%d military unit may impose martial law.", + "Up to %d military units may impose martial " + "law.", mlmax), mlmax); } -astr_add(&str, - /* TRANS: Martial law closing parenthesis */ - _("%d per unit). "), - get_city_bonus(pcity, EFT_MARTIAL_LAW_EACH)); +astr_add_line(&str, PL_("Each military unit makes %d " +"unhappy citizen content.", +"Each military unit makes %d " +"unhappy citizens content.", +mleach), mleach); } else if (uhcfac > 0) { astr_add_line(&str, _("Military units in the field may cause unhappiness. ")); ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40686) [Patch] (i18n) Fix typo and phrasing in helpdata.txt
http://bugs.freeciv.org/Ticket/Display.html?id=40686 > As reported on freeciv-i18n. --- では、拳で接触します。 commit b7d0556ad532ae2dc205b0128094df6fd455dca9 Author: Madeline Book Date: Tue Jan 27 15:47:34 2009 -0500 Fix typo and awkward phrasing. Reported by: Sini Ruohomaa --- data/helpdata.txt | 12 ++-- 1 files changed, 6 insertions(+), 6 deletions(-) diff --git a/data/helpdata.txt b/data/helpdata.txt index c469ec9..075f269 100644 --- a/data/helpdata.txt +++ b/data/helpdata.txt @@ -779,12 +779,12 @@ other player isn't getting a better deal than you expect.\ Cease-fire, Armistice, Peace, and Alliance. The first is the default state, \ while the others can be achieved by signing diplomatic treaties.\ "), _("\ - To have a diplomatic relationship with another player, you must fist \ -establish first contact with that player. To establish first contact, you \ -have to move one of your units next to a city or unit belonging to that \ -player, or vice versa. Unless you establish an embassy with that player, \ -you may again lose contact with them after a set number of turns without \ -direct physical contact.\ + To have a diplomatic relationship with another player, you must first \ +establish contact with that player. To establish contact, you have to move \ +one of your units next to a city or unit belonging to that player, or vice \ +versa. Unless you establish an embassy with that player, you may again \ +lose contact with them after a set number of turns without direct physical \ +contact.\ "), _("\ The diplomatic state between players defaults to War. \ During War, you can freely move you units inside enemy territory and \ ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40687) [Patch] (i18n) Fix gold upkeep message missing period
http://bugs.freeciv.org/Ticket/Display.html?id=40687 > As reported on freeciv-i18n. --- かわいそうな兵士ね。どうしようかな。 diff --git a/server/unittools.c b/server/unittools.c index 8576975..8b72d6a 100644 --- a/server/unittools.c +++ b/server/unittools.c @@ -295,8 +295,9 @@ void pay_for_units(struct player *pplayer, struct city *pcity) assert(pplayer->economic.gold + potential_gold >= 0); notify_player(pplayer, NULL, E_UNIT_LOST_MISC, - _("Not enough gold. %s disbanded"), - unit_name_translation(punit)); +_("Not enough gold to pay upkeep " + "for %s. Unit disbanded."), +unit_name_translation(punit)); wipe_unit(punit); } else { /* Gold can get negative here as city improvements will be sold commit 03fb5090ea513fe6676357fddb3f348a2a6236f8 Author: Madeline Book Date: Tue Jan 27 15:53:27 2009 -0500 Fix missing period and phrasing of unit gold upkeep message. Reported by: Sini Ruohomaa --- server/unittools.c |5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/server/unittools.c b/server/unittools.c index 455a9bb..9188e2d 100644 --- a/server/unittools.c +++ b/server/unittools.c @@ -294,8 +294,9 @@ void pay_for_units(struct player *pplayer, struct city *pcity) assert(pplayer->economic.gold + potential_gold >= 0); notify_player(pplayer, NULL, E_UNIT_LOST, - _("Not enough gold. %s disbanded"), - unit_name_translation(punit)); +_("Not enough gold to pay upkeep " + "for %s. Unit disbanded."), +unit_name_translation(punit)); wipe_unit(punit); } else { /* Gold can get negative here as city improvements will be sold ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40688) [Patch] (i18n) Fix civil war message
http://bugs.freeciv.org/Ticket/Display.html?id=40688 > As reported on freeciv-i18n. --- 趣味は?内戦煽動。 commit 27c85d0b02e5e7cb12155a0d4a41dcd20d7cf81b Author: Madeline Book Date: Tue Jan 27 16:06:51 2009 -0500 Fix double space and grammar in civil war message. Reported by: Sini Ruohomaa diff --git a/server/plrhand.c b/server/plrhand.c index 1dd6184..f96c822 100644 --- a/server/plrhand.c +++ b/server/plrhand.c @@ -1683,9 +1683,9 @@ void civil_war(struct player *pplayer) nation_rule_name(nation_of_player(pplayer)), player_name(cplayer)); notify_player(pplayer, NULL, E_CIVIL_WAR, - _("Your nation is thrust into civil war, " - " %s is declared the leader of the rebel states."), - player_name(cplayer)); +_("Your nation is thrust into civil war! " + "%s is declared the leader of the rebel states."), +player_name(cplayer)); i = city_list_size(pplayer->cities)/2; /* number to flip */ j = city_list_size(pplayer->cities); /* number left to process */ ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40689) [Patch] (i18n) Fix " of the " construct
http://bugs.freeciv.org/Ticket/Display.html?id=40689 > As reported on freeciv-i18n by Sini Ruohomaa, the attached patches fix two instances of "%s of the %s" (" of the ") contruct in translated strings. The strings are replaced by "?nationgovernment:%s %s" (i.e. " "). --- 英語の文法はめちゃくちゃじゃないか。 client/text.c | 18 ++ server/report.c | 10 ++ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/client/text.c b/client/text.c index e2c2b71..81c52ca 100644 --- a/client/text.c +++ b/client/text.c @@ -1165,21 +1165,23 @@ const char *get_score_text(const struct player *pplayer) const char *get_report_title(const char *report_name) { static struct astring str = ASTRING_INIT; + const struct player *pplayer = client.conn.playing; astr_clear(&str); astr_add_line(&str, "%s", report_name); - if (NULL != client.conn.playing) { -/* TRANS: "Republic of the Poles" */ -astr_add_line(&str, _("%s of the %s"), - government_name_for_player(client.conn.playing), - nation_plural_for_player(client.conn.playing)); + if (pplayer != NULL) { +/* TRANS: . + * E.g. "Polish Republic". */ +astr_add_line(&str, _("?nationgovernment:%s %s"), + nation_adjective_for_player(pplayer), + government_name_for_player(pplayer)); astr_add_line(&str, "%s %s: %s", - ruler_title_translation(client.conn.playing), - player_name(client.conn.playing), - textyear(game.info.year)); + ruler_title_translation(pplayer), + player_name(pplayer), + textyear(game.info.year)); } else { /* TRANS: "Observer: 1985" */ astr_add_line(&str, _("Observer: %s"), diff --git a/server/report.c b/server/report.c index 52cbe04..f650d93 100644 --- a/server/report.c +++ b/server/report.c @@ -791,10 +791,12 @@ void report_demographics(struct connection *pconn) return; } - my_snprintf(civbuf, sizeof(civbuf), _("The %s of the %s (%s)"), - government_name_for_player(pplayer), - nation_plural_for_player(pplayer), - textyear(game.info.year)); + /* TRANS: (). + * E.g. "Polish Despotism (200 AD)". */ + my_snprintf(civbuf, sizeof(civbuf), _("%s %s (%s)"), + nation_adjective_for_player(pplayer), + government_name_for_player(pplayer), + textyear(game.info.year)); buffer[0] = '\0'; for (i = 0; i < ARRAY_SIZE(rowtable); i++) { client/text.c | 18 ++ server/report.c | 10 ++ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/client/text.c b/client/text.c index 9295f14..a1d9a2e 100644 --- a/client/text.c +++ b/client/text.c @@ -1117,21 +1117,23 @@ const char *get_score_text(const struct player *pplayer) const char *get_report_title(const char *report_name) { static struct astring str = ASTRING_INIT; + const struct player *pplayer = game.player_ptr; astr_clear(&str); astr_add_line(&str, "%s", report_name); - if (game.player_ptr) { -/* TRANS: "Republic of the Poles" */ -astr_add_line(&str, _("%s of the %s"), - government_name_for_player(game.player_ptr), - nation_plural_for_player(game.player_ptr)); + if (pplayer != NULL) { +/* TRANS: . + * E.g. "Polish Republic". */ +astr_add_line(&str, _("?nationgovernment:%s %s"), + nation_adjective_for_player(pplayer), + government_name_for_player(pplayer)); astr_add_line(&str, "%s %s: %s", - ruler_title_translation(game.player_ptr), - player_name(game.player_ptr), - textyear(game.info.year)); + ruler_title_translation(pplayer), + player_name(pplayer), + textyear(game.info.year)); } else { /* TRANS: "Observer: 1985" */ astr_add_line(&str, _("Observer: %s"), diff --git a/server/report.c b/server/report.c index 7bb265e..ef64d6e 100644 --- a/server/report.c +++ b/server/report.c @@ -745,10 +745,12 @@ void report_demographics(struct connection *pconn) return; } - my_snprintf(civbuf, sizeof(civbuf), _("The %s of the %s (%s)"), - government_name_for_player(pplayer), - nation_plural_for_player(pplayer), - textyear(game.info.year)); + /* TRANS: (). + * E.g. "Polish Despotism (200 AD)". */ + my_snprintf(civbuf, sizeof(civbuf), _("%s %s (%s)"), + nation_adjective_for_player(pplayer), + government_name_for_player(pplayer), + textyear(game.info.year)); buffer[0] = '\0'; for (i = 0; i < ARRAY_SIZE(rowtable); i++) { ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40690) [Patch] (i18n) Do not translate game loading error message
http://bugs.freeciv.org/Ticket/Display.html?id=40690 > As per the i18n guide the attached patches remove a LOG_ERROR message from translation. Actually I'm not sure how much the original author expected users to see this message (and if they should really be made aware of it) rather than using it as a debugging tool. --- 違法な考えの構造が検出された。 diff --git a/server/savegame.c b/server/savegame.c index 1e79b76..3baffb8 100644 --- a/server/savegame.c +++ b/server/savegame.c @@ -4682,11 +4682,10 @@ static void game_load_internal(struct section_file *file) && pplayers_allied(plr, aplayer) && pplayer_can_make_treaty(plr, aplayer, DS_ALLIANCE) == DIPL_ALLIANCE_PROBLEM) { - /* TRANS: ... alliance to */ - freelog(LOG_ERROR, _("Illegal alliance structure detected: " - "%s alliance to %s reduced to peace treaty."), - nation_adjective_for_player(plr), - nation_plural_for_player(aplayer)); + freelog(LOG_ERROR, "Illegal alliance structure detected: " + "%s alliance to %s reduced to peace treaty.", + nation_rule_name(nation_of_player(plr)), + nation_rule_name(nation_of_player(aplayer))); plr->diplstates[player_index(aplayer)].type = DS_PEACE; aplayer->diplstates[player_index(plr)].type = DS_PEACE; } diff --git a/server/savegame.c b/server/savegame.c index 711c22f..2037bac 100644 --- a/server/savegame.c +++ b/server/savegame.c @@ -4069,11 +4069,10 @@ void game_load(struct section_file *file) && pplayers_allied(plr, aplayer) && pplayer_can_make_treaty(plr, aplayer, DS_ALLIANCE) == DIPL_ALLIANCE_PROBLEM) { - /* TRANS: ... alliance to */ - freelog(LOG_ERROR, _("Illegal alliance structure detected: " - "%s alliance to %s reduced to peace treaty."), - nation_adjective_for_player(plr), - nation_plural_for_player(aplayer)); + freelog(LOG_ERROR, "Illegal alliance structure detected: " + "%s alliance to %s reduced to peace treaty.", + nation_rule_name(plr->nation), + nation_rule_name(aplayer->nation)); plr->diplstates[aplayer->player_no].type = DS_PEACE; aplayer->diplstates[plr->player_no].type = DS_PEACE; } ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40691) [Patch] (i18n) Fix some sdl strings.
http://bugs.freeciv.org/Ticket/Display.html?id=40691 > As reported on i18n. The SDL_ttf error message typo appears to have already been fixed in trunk. --- 脳の初期化は中断しています。 commit 7b93f71bfcb0ba2e640bf512d045c872dd080cfe Author: Madeline Book Date: Tue Jan 27 16:11:55 2009 -0500 Fix typo and remove unused code block in sdl code. Reported by: Sini Ruohomaa diff --git a/client/gui-sdl/graphics.c b/client/gui-sdl/graphics.c index c9f10c9..25daf43 100644 --- a/client/gui-sdl/graphics.c +++ b/client/gui-sdl/graphics.c @@ -1018,8 +1018,8 @@ void init_sdl(int iFlags) /* Initialize the TTF library */ if (TTF_Init() < 0) { -freelog(LOG_FATAL, _("Unable to initialize SDL_ttf library: %s"), - SDL_GetError()); +freelog(LOG_FATAL, _("Unable to initialize SDL_ttf library: %s"), +SDL_GetError()); exit(2); } diff --git a/client/gui-sdl/gui_string.c b/client/gui-sdl/gui_string.c index 7f8bce7..0a65db5 100644 --- a/client/gui-sdl/gui_string.c +++ b/client/gui-sdl/gui_string.c @@ -601,15 +601,6 @@ static TTF_Font * load_font(Uint16 ptsize) if(!pFont_with_FullPath) { const char *path = theme_font_filename(theme); -#if 0 -if(!path) { - path = datafilename("stdfont.ttf"); - if (!path) { - die(_("Couldn't find stdfont.ttf file. Please link/copy/move any" -"unicode ttf font to data dir as stdfont.ttf")); -} -} -#endif pFont_with_FullPath = mystrdup(path); assert(pFont_with_FullPath != NULL); } diff --git a/client/gui-sdl/gui_string.c b/client/gui-sdl/gui_string.c index 7f8bce7..0a65db5 100644 --- a/client/gui-sdl/gui_string.c +++ b/client/gui-sdl/gui_string.c @@ -601,15 +601,6 @@ static TTF_Font * load_font(Uint16 ptsize) if(!pFont_with_FullPath) { const char *path = theme_font_filename(theme); -#if 0 -if(!path) { - path = datafilename("stdfont.ttf"); - if (!path) { - die(_("Couldn't find stdfont.ttf file. Please link/copy/move any" -"unicode ttf font to data dir as stdfont.ttf")); -} -} -#endif pFont_with_FullPath = mystrdup(path); assert(pFont_with_FullPath != NULL); } ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40692) [Patch] Capitalize nation plural in civilization frame label
http://bugs.freeciv.org/Ticket/Display.html?id=40692 > It was suggested on freeciv-i18n that the nation name looks bad in certain locales as an uncapitalized adjective in the civilization frame label (the frame just below the overview a.k.a. minimap). The attached patches changes the function update_info_label() to set the frame label using the nation plural name, and to capitalize the first letter of the translated string. The function my_toupper() is used to set the first char value of the string to uppercase; as far as I can see in the cases where there is no corresponding upper case form for the character, my_toupper() will just return the same value that was passed in, so there should not be any inadvertent string corruption. --- 文字化けしないでください。 diff --git a/client/gui-gtk-2.0/mapview.c b/client/gui-gtk-2.0/mapview.c index 4d4acc2..e691104 100644 --- a/client/gui-gtk-2.0/mapview.c +++ b/client/gui-gtk-2.0/mapview.c @@ -102,11 +102,22 @@ void update_timeout_label(void) void update_info_label( void ) { GtkWidget *label; + const struct player *pplayer = client.conn.playing; label = gtk_frame_get_label_widget(GTK_FRAME(main_frame_civ_name)); - if (NULL != client.conn.playing) { -gtk_label_set_text(GTK_LABEL(label), - nation_plural_for_player(client.conn.playing)); + if (pplayer != NULL) { +char nation[MAX_LEN_NAME]; + +/* Capitalize the first character of the translated nation + * plural name so that the frame label looks good. I assume + * that in the case that capitalization does not make sense + * (e.g. multi-byte characters or no "upper case" form in + * the translation language) my_toupper() will just return + * the same value as was passed into it. */ +sz_strlcpy(nation, nation_plural_for_player(pplayer)); +nation[0] = my_toupper(nation[0]); + +gtk_label_set_text(GTK_LABEL(label), nation); } else { gtk_label_set_text(GTK_LABEL(label), "-"); } diff --git a/client/gui-gtk-2.0/mapview.c b/client/gui-gtk-2.0/mapview.c index 0c7ece5..0c9412a 100644 --- a/client/gui-gtk-2.0/mapview.c +++ b/client/gui-gtk-2.0/mapview.c @@ -98,11 +98,22 @@ void update_timeout_label(void) void update_info_label( void ) { GtkWidget *label; + const struct player *pplayer = game.player_ptr; label = gtk_frame_get_label_widget(GTK_FRAME(main_frame_civ_name)); - if (game.player_ptr) { -gtk_label_set_text(GTK_LABEL(label), - nation_adjective_for_player(game.player_ptr)); + if (pplayer != NULL) { +char nation[MAX_LEN_NAME]; + +/* Capitalize the first character of the translated nation + * plural name so that the frame label looks good. I assume + * that in the case that capitalization does not make sense + * (e.g. multi-byte characters or no "upper case" form in + * the translation language) my_toupper() will just return + * the same value as was passed into it. */ +sz_strlcpy(nation, nation_plural_for_player(pplayer)); +nation[0] = my_toupper(nation[0]); + +gtk_label_set_text(GTK_LABEL(label), nation); } else { gtk_label_set_text(GTK_LABEL(label), "-"); } ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40693) [Patch] (i18n) Fix veteran notify message grammar
http://bugs.freeciv.org/Ticket/Display.html?id=40693 > As reported on freeciv-i18n, the attached patches fix the "And, became more experienced!" event message grammar by making the function notify_unit_experience() not attempt to link up to previous event message. So for example the user will now see: "Your diplomat succeeded in bribing the musketeer." "Your diplomat became more experienced!" and will have to figure out that the veterancy was due to the just prior event. --- 子供のように扱うな! server/diplomats.c |6 +++--- server/unithand.c |4 ++-- server/unittools.c | 27 --- server/unittools.h |2 +- 4 files changed, 18 insertions(+), 21 deletions(-) diff --git a/server/diplomats.c b/server/diplomats.c index 845fe62..888e3a8 100644 --- a/server/diplomats.c +++ b/server/diplomats.c @@ -456,7 +456,7 @@ void diplomat_bribe(struct player *pplayer, struct unit *pdiplomat, unit_name_translation(pdiplomat), unit_name_translation(pvictim)); if (maybe_make_veteran(pdiplomat)) { -notify_unit_experience(pdiplomat, TRUE); +notify_unit_experience(pdiplomat); } notify_player(uplayer, pvictim->tile, E_ENEMY_DIPLOMAT_BRIBE, /* TRANS: ... */ @@ -1138,7 +1138,7 @@ static bool diplomat_infiltrate_tile(struct player *pplayer, /* Defending unit became more experienced? */ if (maybe_make_veteran(punit)) { - notify_unit_experience(punit, FALSE); + notify_unit_experience(punit); } wipe_unit(pdiplomat); return FALSE; @@ -1187,7 +1187,7 @@ static void diplomat_escape(struct player *pplayer, struct unit *pdiplomat, unit_name_translation(pdiplomat), city_name(spyhome)); if (maybe_make_veteran(pdiplomat)) { - notify_unit_experience(pdiplomat, TRUE); + notify_unit_experience(pdiplomat); } /* being teleported costs all movement */ diff --git a/server/unithand.c b/server/unithand.c index 7ffa30a..d5e8c8d 100644 --- a/server/unithand.c +++ b/server/unithand.c @@ -784,7 +784,7 @@ static bool unit_bombard(struct unit *punit, struct tile *ptile) } if (maybe_make_veteran(punit)) { -notify_unit_experience(punit, FALSE); +notify_unit_experience(punit); } send_unit_info(NULL, punit); @@ -903,7 +903,7 @@ static void handle_unit_attack_request(struct unit *punit, struct unit *pdefende nation_adjective_for_player(unit_owner(plooser)), unit_name_translation(plooser)); if (vet) { - notify_unit_experience(pwinner, TRUE); + notify_unit_experience(pwinner); } notify_player(unit_owner(plooser), def_tile, E_UNIT_LOST_ATT, /* TRANS: "... Cannon ... the Polish Destroyer." */ diff --git a/server/unittools.c b/server/unittools.c index 455a9bb..83de20e 100644 --- a/server/unittools.c +++ b/server/unittools.c @@ -605,21 +605,18 @@ static bool maybe_settler_become_veteran(struct unit *punit) } /** - common notification for all experience levels. - When used immediately after another unit message, set also to TRUE. + Common notification for all experience levels. **/ -void notify_unit_experience(struct unit *punit, bool also) +void notify_unit_experience(struct unit *punit) { - if (also) { -notify_player(unit_owner(punit), punit->tile, E_UNIT_BECAME_VET, - /* TRANS: And, became ... */ - _("And, became more experienced!")); - } else { -notify_player(unit_owner(punit), punit->tile, E_UNIT_BECAME_VET, - /* TRANS: Your became ... */ - _("Your %s became more experienced!"), - unit_name_translation(punit)); + if (!punit) { +return; } + + notify_player(unit_owner(punit), punit->tile, E_UNIT_BECAME_VET, +/* TRANS: Your became ... */ +_("Your %s became more experienced!"), +unit_name_translation(punit)); } /** @@ -645,7 +642,7 @@ static void update_unit_activity(struct unit *punit) /* settler may become veteran when doing something useful */ if (activity != ACTIVITY_FORTIFYING && activity != ACTIVITY_SENTRY && maybe_settler_become_veteran(punit)) { - notify_unit_experience(punit, FALSE); + notify_unit_experience(punit); } } @@ -1547,7 +1544,7 @@ void kill_unit(struct unit *pkiller, struct unit *punit, bool vet) nation_adjective_for_player(pvictim), unit_name_translation(punit)); if (vet) { - notify_unit_experience(pkiller, TRUE); + notify_unit_experience(pkiller); } notify_player(pvictim, punit->tile, E_UNIT_LOST, /* TRANS: "Cannon ... the Polish Destroyer." */ @@ -1594,7 +1591,7 @@ void kill_unit(struct unit *pkiller, struct unit *punit, bool vet) unit_name_translation(punit), unitcount - 1); if (vet) { -
[Freeciv-Dev] (PR#40667) [Patch] Drawing traderoutes as lines on the mapview
http://bugs.freeciv.org/Ticket/Display.html?id=40667 > > [book - Mon Jan 19 03:31:45 2009]: > > Attached patch implements traderoute line drawing on the main > map view. [...] Version 2 uses cyan (i.e. the goto line color) instead of green for improved visibility. --- まだ誘惑に負けないか。 diff --git a/client/mapview_common.c b/client/mapview_common.c index 518b6fd..11f9402 100644 --- a/client/mapview_common.c +++ b/client/mapview_common.c @@ -25,6 +25,7 @@ #include "timing.h" /* common */ +#include "game.h" #include "map.h" #include "unitlist.h" @@ -72,6 +73,15 @@ static void queue_mapview_update(enum update_type update); static void queue_mapview_tile_update(struct tile *ptile, enum tile_update_type type); +/* Helper struct for drawing traderoutes. */ +struct traderoute_line { + int x, y, width, height; +}; + +/* A traderoute line might need to be drawn in two parts. */ +static const int MAX_TRADEROUTE_DRAW_LINES = 2; + + /** Refreshes a single tile on the map canvas. **/ @@ -1078,6 +1088,129 @@ static void put_one_tile(struct canvas *pcanvas, enum mapview_layer layer, } /** + Depending on where ptile1 and ptile2 are on the map canvas, a traderoute + line may need to be drawn as two disjointed line segments. This function + fills the given line array 'lines' with the necessary line segments. + + The return value is the number of line segments that need to be drawn. + + NB: It is assumed ptile1 and ptile2 are already consistently ordered. + NB: 'lines' must be able to hold least MAX_TRADEROUTE_DRAW_LINES + elements. +**/ +static int traderoute_to_canvas_lines(const struct tile *ptile1, + const struct tile *ptile2, + struct traderoute_line *lines) +{ + int dx, dy; + + if (!ptile1 || !ptile2 || !lines) { +return 0; + } + + base_map_distance_vector(&dx, &dy, TILE_XY(ptile1), TILE_XY(ptile2)); + map_to_gui_pos(tileset, &lines[0].width, &lines[0].height, dx, dy); + + /* FIXME: Remove these casts. */ + tile_to_canvas_pos(&lines[0].x, &lines[0].y, (struct tile *)ptile1); + tile_to_canvas_pos(&lines[1].x, &lines[1].y, (struct tile *)ptile2); + + if (lines[1].x - lines[0].x == lines[0].width + && lines[1].y - lines[0].y == lines[0].height) { +return 1; + } + + lines[1].width = -lines[0].width; + lines[1].height = -lines[0].height; + return 2; +} + +/** + Draw a colored traderoute line from one tile to another. +**/ +static void draw_traderoute_line(const struct tile *ptile1, + const struct tile *ptile2, + enum color_std color) +{ + struct traderoute_line lines[MAX_TRADEROUTE_DRAW_LINES]; + int line_count, i; + struct color *pcolor; + + if (!ptile1 || !ptile2) { +return; + } + + pcolor = get_color(tileset, color); + if (!pcolor) { +return; + } + + /* Order the source and destination tiles consistently + * so that if a line is drawn twice it does not produce + * ugly effects due to dashes not lining up. */ + if (tile_index(ptile2) > tile_index(ptile1)) { +const struct tile *tmp; +tmp = ptile1; +ptile1 = ptile2; +ptile2 = tmp; + } + + line_count = traderoute_to_canvas_lines(ptile1, ptile2, lines); + for (i = 0; i < line_count; i++) { +canvas_put_line(mapview.store, pcolor, LINE_BORDER, +lines[i].x + tileset_tile_width(tileset) / 2, +lines[i].y + tileset_tile_height(tileset) / 2, +lines[i].width, lines[i].height); + } +} + +/** + Draw all traderoutes for the given city. +**/ +static void draw_traderoutes_for_city(const struct city *pcity_src) +{ + int i; + const struct city *pcity_dest; + + if (!pcity_src) { +return; + } + + for (i = 0; i < NUM_TRADEROUTES; i++) { +pcity_dest = game_find_city_by_number(pcity_src->trade[i]); +if (!pcity_dest) { + continue; +} +draw_traderoute_line(city_tile(pcity_src), city_tile(pcity_dest), + COLOR_MAPVIEW_GOTO); /* Cyan. */ + } +} + +/** + Draw traderoutes between cities as lines on the main map canvas. +**/ +static void draw_traderoutes(void) +{ + if (!d