[Freeciv-Dev] (PR#40283) [Patch] Skip base specials in tile_special_type_iterate
http://bugs.freeciv.org/Ticket/Display.html?id=40283 > Committed to S2_2 (r14784) and trunk (r14785). -- ファイドのことを頼むぞ。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
Re: [Freeciv-Dev] (PR#40283) [Patch] Skip base specials in tile_special_type_iterate
http://bugs.freeciv.org/Ticket/Display.html?id=40283 > On 17/06/2008, Madeline Book wrote: > So getting back on topic, is this an acceptable step > for removing S_FORTRESS and S_AIRBASE from specials, > that I may commit to S2_2/trunk so as to be able to > fix the base handling in the editor? Explicit Yes - ML ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40283) [Patch] Skip base specials in tile_special_type_iterate
http://bugs.freeciv.org/Ticket/Display.html?id=40283 > The previous two posts went off on a tangent that is not really important at the moment. So getting back on topic, is this an acceptable step for removing S_FORTRESS and S_AIRBASE from specials, that I may commit to S2_2/trunk so as to be able to fix the base handling in the editor? I will test it myself some more and will take silence (while other stuff is being done) as a 'yes'. ;) -- やってもいいですか。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40283) [Patch] Skip base specials in tile_special_type_iterate
http://bugs.freeciv.org/Ticket/Display.html?id=40283 > > [EMAIL PROTECTED] - Sun Jun 15 23:02:28 2008]: > > 2008/6/16 Madeline Book: > > I have also written the code with the future feature > > of more than one base type being allowed per tile in > > mind. This should be possible (since indeed it was > > allowed to have a fortress and an airbase on the same > > tile before), but I will start a new ticket for this > > issue later. > > You mean that since they have been stored as separate bits (and not > as id number), it would have been possible to have them independently > in same tile. I don't think it has ever been really possible for > player. Fortress and airbase have replaced each other. I think this is > correct behavior. Do you have some good use-case where multiple bases > should exist in same tile? In warserver (i.e. 2.0) games it sometimes happens that a city on one island is 11 tiles (real distance) from a city on another island and there is only one tile beside the first city that is 10 tiles away from the second city. Now the player would like the send fighters between the two cities (either to attack or to transfer them somewhere) or paradrop, both of which are limited to 10 tiles away. The usual trick in that case is to build a fortress+airbase on the tile that is 10 tiles away and have some defenders protect the fighters there. This is much faster and safer than say using some transport+engineers to terraform ocean into land and build a city 9 tiles away. It doesn't happen often, but it does happen. Anyway I'm sure many players would cry if they found out that suddenly you are not allowed to build a fortress and an airbase on the same tile. ;) > Note that even with just one base/tile main reason I have not pushed > gen-base code in faster is memory and disk space (savegame) usage. > There will be player num (FoW, what players believe)) + 1 (truth) base > maps. If you allow multiple bases in the same tile, you need one > bit/tile/basetype. With just one base/tile you can have > 2^(bits/tile)-1 base types. I even consider adding just one more > base type in next version by using those specials bits we have > been using until now. Let's assume there can be a maximum of 8 base types. Taking the worst possible case of a 256x256 tile map with 32 players in it means we have 33 maps of 65536 tiles or 2162688 tiles total for the server to keep track of (or to be stored in the savegame). Now if we allowed multiple base types on the same tile we need a byte (8 bits) per tile to keep track of which bases are on a tile, giving 2162688 total bytes used to keep track of this information. If we allow only one base type per tile at a time, then we need 3 bits per tile (lg(8)), or 811008 bytes total. So in the worst possible case for our 8 base types of which only one type can exist at a tile at a time, the server saves not more than one and a half megabytes of memory. I would think that this would be a very small portion compared to its total memory use (which, for example in the worst case above, would probably be a few 100 megabytes). As for savegames, the saving would probably be a bit more considering that the data is saved in a human editable format. But I assume a server would also have much more disk space (at least compared to RAM) and that the savegames would be compressed. So the saving is not that useful in the first place. Therefore, in my opinion, the advantages due to space savings and the configurability of base types does not out-weigh the disadvantage of losing a gameplay ability (which from the vast majority of users' points of view would look like it was removed for no obvious reason). But there is a somewhat deeper problem that I have noticed now; if we were to decide that multiple base types were allowed to exist on a tile at the same time, then something would need to be done about S_PILLAGE_BASE and related code. We would need a new mechanism to encode the "activity target" in the pillage activity both as entered in the client and handled at the server. :( Finally, for far, far future considerations, if ever specials are generalized to be fully loaded from rulesets, I assume that military bases could be merged into this ruleset type. Then since most special types can coexist on a tile, we would once again have multiple base types allowed on a tile at the same time. -- ちょっと長くなりましたね。 ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
Re: [Freeciv-Dev] (PR#40283) [Patch] Skip base specials in tile_special_type_iterate
http://bugs.freeciv.org/Ticket/Display.html?id=40283 > 2008/6/16 Madeline Book: > I have also written the code with the future feature > of more than one base type being allowed per tile in > mind. This should be possible (since indeed it was > allowed to have a fortress and an airbase on the same > tile before), but I will start a new ticket for this > issue later. You mean that since they have been stored as separate bits (and not as id number), it would have been possible to have them independently in same tile. I don't think it has ever been really possible for player. Fortress and airbase have replaced each other. I think this is correct behavior. Do you have some good use-case where multiple bases should exist in same tile? Note that even with just one base/tile main reason I have not pushed gen-base code in faster is memory and disk space (savegame) usage. There will be player num (FoW, what players believe)) + 1 (truth) base maps. If you allow multiple bases in the same tile, you need one bit/tile/basetype. With just one base/tile you can have 2^(bits/tile)-1 base types. I even consider adding just one more base type in next version by using those specials bits we have been using until now. - ML ___ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev
[Freeciv-Dev] (PR#40283) [Patch] Skip base specials in tile_special_type_iterate
http://bugs.freeciv.org/Ticket/Display.html?id=40283 > Attached patch makes tile_special_type_iterate skip over S_FORTRESS and S_AIRBASE in order to facilitate the transition of base types out of specials (as mentioned in PR#40184). Any code that depended on the base special values being in the iteration has also been updated; there should be no change in behaviour if I have not made any mistakes. In the future when bases really are removed from enum tile_special_type, all of the added base/special transition code can be made inert by simply having base_get_tile_special_type always return S_LAST. I have also written the code with the future feature of more than one base type being allowed per tile in mind. This should be possible (since indeed it was allowed to have a fortress and an airbase on the same tile before), but I will start a new ticket for this issue later. -- よろしくやるのは気持ちいいですね diff --git a/client/packhand.c b/client/packhand.c index c97bc71..9a900fe 100644 --- a/client/packhand.c +++ b/client/packhand.c @@ -2242,6 +2242,24 @@ void handle_tile_info(struct packet_tile_info *packet) } } tile_special_type_iterate_end; + base_type_iterate(pbase) { +int spe = base_get_tile_special_type(pbase); +if (!(0 <= spe && spe < S_LAST)) { + continue; +} +if (packet->special[spe]) { + if (!tile_has_base(ptile, pbase)) { +tile_add_base(ptile, pbase); +tile_changed = TRUE; + } +} else { + if (tile_has_base(ptile, pbase)) { +tile_remove_base(ptile, pbase); +tile_changed = TRUE; + } +} + } base_type_iterate_end; + tile_changed = tile_changed || (tile_resource(ptile) != presource); /* always called after setting terrain */ diff --git a/common/base.c b/common/base.c index 884bd22..bb3f8e0 100644 --- a/common/base.c +++ b/common/base.c @@ -265,3 +265,29 @@ struct base_type *get_base_by_gui_type(enum base_gui_type type, return NULL; } + +/** + Returns the value from enum tile_special_type that corresponds to this + base type or S_LAST if no such value exists. + + NB: This function should only be used temporarily while the old "special" + base code is transitioned to the new generalized bases. Once S_FORTRESS + and S_AIRBASE are removed from specials, this function should also be + removed. +**/ +int base_get_tile_special_type(const struct base_type *pbase) +{ + if (!pbase) { +return S_LAST; + } + + if (base_number(pbase) == BASE_FORTRESS) { +return S_FORTRESS; + } + + if (base_number(pbase) == BASE_AIRBASE) { +return S_AIRBASE; + } + + return S_LAST; +} diff --git a/common/base.h b/common/base.h index ba38a5c..a6e5f3c 100644 --- a/common/base.h +++ b/common/base.h @@ -66,7 +66,11 @@ Base_type_id base_index(const struct base_type *pbase); Base_type_id base_number(const struct base_type *pbase); struct base_type *base_by_number(const Base_type_id id); + +/* Compatibility functions for the old "special" + * type bases which are being phased out. */ struct base_type *base_of_bv_special(bv_special spe); +int base_get_tile_special_type(const struct base_type *pbase); const char *base_rule_name(const struct base_type *pbase); const char *base_name_translation(struct base_type *pbase); diff --git a/common/terrain.c b/common/terrain.c index d7d4e6f..eec85f5 100644 --- a/common/terrain.c +++ b/common/terrain.c @@ -547,6 +547,7 @@ static const char *tile_special_type_names[] = / enum tile_special_type find_special_by_rule_name(const char *name) { + int spe; assert(ARRAY_SIZE(tile_special_type_names) == S_LAST); tile_special_type_iterate(i) { @@ -555,6 +556,16 @@ enum tile_special_type find_special_by_rule_name(const char *name) } } tile_special_type_iterate_end; + base_type_iterate(pbase) { +spe = base_get_tile_special_type(pbase); +if (!(0 <= spe && spe < S_LAST)) { + continue; +} +if (0 == strcmp(tile_special_type_names[spe], name)) { + return spe; +} + } base_type_iterate_end; + return S_LAST; } diff --git a/common/terrain.h b/common/terrain.h index 7e80403..8fdfe0f 100644 --- a/common/terrain.h +++ b/common/terrain.h @@ -55,13 +55,19 @@ extern enum tile_special_type infrastructure_specials[]; BV_DEFINE(bv_special, S_LAST_PLUS); -#define tile_special_type_iterate(special)\ -{ \ - enum tile_special_type special = 0; \ - for (; special < S_LAST; special++) { - -#define tile_special_type_iterate_end \ - } \ +/* NB: This does not include S_FORTRESS and S_AIRBASE. + * You must use base_type_iterate and related accessors + * in base.h for those. */ +#define tile_special_type_iterate(special