diff -u3NrX /home/perrin/freeciv/diff_ignore freeciv/common/packets.c freeciv-phased/common/packets.c --- freeciv/common/packets.c Thu Apr 25 19:54:18 2002 +++ freeciv-phased/common/packets.c Tue May 14 00:02:17 2002 @@ -3085,6 +3085,9 @@ const struct packet_ruleset_unit *packet) { unsigned char buffer[MAX_LEN_PACKET], *cptr; + int i; + char *buf; + cptr=put_uint8(buffer+2, PACKET_RULESET_UNIT); cptr=put_uint8(cptr, packet->id); @@ -3100,8 +3103,14 @@ cptr=put_uint8(cptr, packet->firepower); cptr=put_uint8(cptr, packet->obsoleted_by); cptr=put_uint8(cptr, packet->fuel); - cptr=put_uint32(cptr, packet->flags); - cptr=put_uint32(cptr, packet->roles); + buf = (char *)(&packet->flags); + for (i = 0; i < sizeof(bv_set); i++) { + cptr=put_uint8(cptr, (int) buf[i]); + } + buf = (char *)(&packet->roles); + for (i = 0; i < sizeof(bv_set); i++) { + cptr=put_uint8(cptr, (int) buf[i]); + } cptr=put_uint8(cptr, packet->happy_cost); /* unit upkeep -- SKi */ cptr=put_uint8(cptr, packet->shield_cost); cptr=put_uint8(cptr, packet->food_cost); @@ -3115,7 +3124,7 @@ cptr = put_string(cptr, packet->sound_fight); cptr = put_string(cptr, packet->sound_fight_alt); } - if(unit_type_flag(packet->id, F_PARATROOPERS)) { + if (unit_type_flag(packet->id, F_PARATROOPERS)) { cptr=put_uint16(cptr, packet->paratroopers_range); cptr=put_uint8(cptr, packet->paratroopers_mr_req); cptr=put_uint8(cptr, packet->paratroopers_mr_sub); @@ -3142,7 +3151,8 @@ struct pack_iter iter; struct packet_ruleset_unit *packet= fc_malloc(sizeof(struct packet_ruleset_unit)); - int len; + int len, i; + char *buf; pack_iter_init(&iter, pc); @@ -3160,8 +3170,14 @@ iget_uint8(&iter, &packet->obsoleted_by); if (packet->obsoleted_by>127) packet->obsoleted_by-=256; iget_uint8(&iter, &packet->fuel); - iget_uint32(&iter, &packet->flags); - iget_uint32(&iter, &packet->roles); + buf = (char *)(&packet->flags); + for (i = 0; i < sizeof(bv_set); i++) { + iget_uint8(&iter, (int *) &buf[i]); + } + buf = (char *)(&packet->roles); + for (i = 0; i < sizeof(bv_set); i++) { + iget_uint8(&iter, (int *) &buf[i]); + } iget_uint8(&iter, &packet->happy_cost); /* unit upkeep -- SKi */ iget_uint8(&iter, &packet->shield_cost); iget_uint8(&iter, &packet->food_cost); @@ -3182,7 +3198,7 @@ sz_strlcpy(packet->sound_fight, "f_generic"); sz_strlcpy(packet->sound_fight_alt, "-"); } - if(TEST_BIT(packet->flags, F_PARATROOPERS)) { + if (BV_ISSET(F_PARATROOPERS, &packet->flags)) { iget_uint16(&iter, &packet->paratroopers_range); iget_uint8(&iter, &packet->paratroopers_mr_req); iget_uint8(&iter, &packet->paratroopers_mr_sub); @@ -3194,7 +3210,7 @@ if (has_capability("pop_cost", pc->capability)) { iget_uint8(&iter, &packet->pop_cost); } else { - packet->pop_cost = TEST_BIT(packet->flags, F_CITIES) ? 1 : 0; + packet->pop_cost = BV_ISSET(F_CITIES, &packet->flags) ? 1 : 0; } len = pack_iter_remaining(&iter); diff -u3NrX /home/perrin/freeciv/diff_ignore freeciv/common/packets.h freeciv-phased/common/packets.h --- freeciv/common/packets.h Thu Apr 18 09:59:17 2002 +++ freeciv-phased/common/packets.h Mon May 13 18:40:44 2002 @@ -599,8 +599,8 @@ int firepower; int obsoleted_by; int fuel; - int flags; - int roles; /* a client-side-ai might be interested */ + bv_set flags; + bv_set roles; int happy_cost; /* unhappy people in home city */ int shield_cost; /* normal upkeep cost */ diff -u3NrX /home/perrin/freeciv/diff_ignore freeciv/common/shared.h freeciv-phased/common/shared.h --- freeciv/common/shared.h Thu Apr 25 19:54:18 2002 +++ freeciv-phased/common/shared.h Mon May 13 23:16:53 2002 @@ -73,6 +73,29 @@ #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +/**** BIT ARRAYS ****/ +#define BV_SETSIZE 64 /* this number MUST be >= 8! */ + +typedef unsigned char uint_8; +#define _BV_DELT(b) ((b) >> 0x3) +#define _BV_MASK(b) (1 << ((b) & 0x7)) +#define _BV_BITS(s) ((s)->bits) + +typedef struct bv_set { + uint_8 bits[_BV_DELT(BV_SETSIZE)]; +} bv_set; + +#define BV_ZERO(s) \ + do { \ + unsigned int _i; \ + for (_i=0; _iflags, F_FANATIC)) return 0; + BV_ISSET(F_FANATIC, &ut->flags)) { + return 0; + } return ut->shield_cost * g->unit_shield_cost_factor; } @@ -163,10 +164,21 @@ /************************************************************************** ... **************************************************************************/ +bool unit_type_flag_or_role(Unit_Type_id id, int flag_or_role) +{ + assert((flag_or_role>=0 && flag_or_role=L_FIRST && flag_or_role=0 && flag=L_FIRST && role F_LAST); if(!first_init) { for(i=0; i= F_LAST */ +#define L_FIRST 128 /* must be >= F_LAST */ enum unit_role_id { L_FIRSTBUILD=L_FIRST, /* is built first when city established */ L_EXPLORER, /* initial explorer unit */ @@ -170,8 +170,8 @@ int obsoleted_by; int fuel; - unsigned int flags; - unsigned int roles; + bv_set flags; + bv_set roles; int happy_cost; /* unhappy people in home city */ int shield_cost; /* normal upkeep cost */ diff -u3NrX /home/perrin/freeciv/diff_ignore freeciv/server/ruleset.c freeciv-phased/server/ruleset.c --- freeciv/server/ruleset.c Tue Apr 30 16:05:02 2002 +++ freeciv-phased/server/ruleset.c Mon May 13 23:27:47 2002 @@ -726,7 +726,9 @@ /* flags */ unit_type_iterate(i) { u = &unit_types[i]; - u->flags = 0; + BV_ZERO(&u->flags); + assert(!BV_ISSET(F_LAST, &u->flags)); + assert(!unit_type_flag(i, F_LAST-1)); slist = secfile_lookup_str_vec(file, &nval, "%s.flags", sec[i]); for(j=0; jflags |= (1<flags |= (1<flags); + BV_SET(F_MISSILE_CARRIER, &u->flags); ival = F_PARTIAL_INVIS; } else { ival = unit_flag_from_str(sval); @@ -747,7 +749,8 @@ freelog(LOG_ERROR, "for unit_type \"%s\": bad flag name \"%s\" (%s)", u->name, sval, filename); } - u->flags |= (1<flags); + assert(unit_type_flag(i, ival)); if(ival == F_PARATROOPERS) { u->paratroopers_range = secfile_lookup_int(file, @@ -768,7 +771,7 @@ /* roles */ unit_type_iterate(i) { u = &unit_types[i]; - u->roles = 0; + BV_ZERO(&u->roles); slist = secfile_lookup_str_vec(file, &nval, "%s.roles", sec[i] ); for(j=0; jname, sval, filename); } - u->roles |= (1<<(ival-L_FIRST)); + BV_SET(ival - L_FIRST, &u->roles); + assert(unit_has_role(i, ival)); } free(slist); } unit_type_iterate_end; lookup_tech_list(file, "u_specials", "partisan_req", game.rtech.partisan_req, filename); - /* Some more consistency checking: */ unit_type_iterate(i) { diff -u3NrX /home/perrin/freeciv/diff_ignore freeciv/server/settlers.c freeciv-phased/server/settlers.c --- freeciv/server/settlers.c Thu Apr 4 03:51:05 2002 +++ freeciv-phased/server/settlers.c Mon May 13 23:27:06 2002 @@ -1535,6 +1535,10 @@ virtualunit.x = pcity->x; virtualunit.y = pcity->y; virtualunit.type = best_role_unit(pcity, F_CITIES); + if (virtualunit.type == U_LAST) { + freelog(LOG_DEBUG, "No F_CITIES role unit available"); + return; + } virtualunit.moves_left = unit_type(&virtualunit)->move_rate; virtualunit.hp = unit_type(&virtualunit)->hp; want = evaluate_city_building(&virtualunit, &gx, &gy, &ferryboat); @@ -1568,6 +1572,10 @@ virtualunit.x = pcity->x; virtualunit.y = pcity->y; virtualunit.type = best_role_unit(pcity, F_SETTLERS); + if (virtualunit.type == U_LAST) { + freelog(LOG_DEBUG, "No F_SETTLERS role unit available"); + return; + } virtualunit.moves_left = unit_type(&virtualunit)->move_rate; virtualunit.hp = unit_type(&virtualunit)->hp; want = evaluate_improvements(&virtualunit, &best_act, &gx, &gy);