[Freeciv-Dev] (PR#12667) A few modpack fixes
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: |
[Freeciv-Dev] (PR#12667) A few modpack fixes |
From: |
"Per I. Mathisen" <per@xxxxxxxxxxx> |
Date: |
Sat, 26 Mar 2005 13:21:48 -0800 |
Reply-to: |
bugs@xxxxxxxxxxx |
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=12667 >
CHANGES:
- Correctly handle rulesets with no F_HELP_WONDER units
- Generate actually helpful error messages from gen req code
- Do no try to unleash barbarians if there are no barbarian units in the
ruleset
- Allow rulesets with no barbarians or hut units
- Moved some freeciv-specific defines from shared.h to fc_types.h
- Add init_units="" list to nation rulesets where you add specific units
this nation should start the game with
I would also like to say that writing rulesets became quite a bit more
daunting with effects.ruleset, although the game mechanics it allows are
quite neat.
- Per
Index: ai/aicity.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aicity.c,v
retrieving revision 1.206
diff -u -r1.206 aicity.c
--- ai/aicity.c 24 Mar 2005 16:41:40 -0000 1.206
+++ ai/aicity.c 26 Mar 2005 21:19:14 -0000
@@ -628,12 +628,13 @@
pcity->ai.downtown = 0;
} city_list_iterate_end;
+ if (num_role_units(F_HELP_WONDER) == 0) {
+ return; /* ruleset has no help wonder unit */
+ }
+
unittype = best_role_unit_for_player(pplayer, F_HELP_WONDER);
if (unittype == U_LAST) {
unittype = get_role_unit(F_HELP_WONDER, 0); /* simulate future unit */
- if (unittype == U_LAST) {
- return; /* ruleset has no help wonder unit */
- }
}
ghost = create_unit_virtual(pplayer, NULL, unittype, 0);
range = unit_move_rate(ghost) * 4;
@@ -752,7 +753,7 @@
int best_candidate_value = 0;
struct city *best_candidate = NULL;
/* Whether ruleset has a help wonder unit type */
- bool has_help = (get_role_unit(F_HELP_WONDER, 0) != U_LAST);
+ bool has_help = (num_role_units(F_HELP_WONDER) > 0);
calculate_city_clusters(pplayer);
Index: common/fc_types.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/fc_types.h,v
retrieving revision 1.15
diff -u -r1.15 fc_types.h
--- common/fc_types.h 14 Mar 2005 20:26:25 -0000 1.15
+++ common/fc_types.h 26 Mar 2005 21:19:16 -0000
@@ -21,6 +21,20 @@
* Nothing in this file should require anything else from the common/
* directory! */
+#define BUG_EMAIL_ADDRESS "bugs@xxxxxxxxxxx"
+#define WEBSITE_URL "http://www.freeciv.org/"
+
+/* MAX_NUM_PLAYERS + MAX_NUM_BARBARIANS <= 32 !!!! */
+#define MAX_NUM_PLAYERS 30
+#define MAX_NUM_BARBARIANS 2
+#define MAX_NUM_CONNECTIONS (2 * (MAX_NUM_PLAYERS + MAX_NUM_BARBARIANS))
+#define MAX_NUM_ITEMS 200 /* eg, unit_types */
+#define MAX_NUM_TECH_LIST 10
+#define MAX_NUM_UNIT_LIST 10
+#define MAX_NUM_BUILDING_LIST 10
+#define MAX_LEN_VET_SHORT_NAME 8
+#define MAX_VET_LEVELS 10
+
enum output_type {
O_FOOD, O_SHIELD, O_TRADE, O_GOLD, O_LUXURY, O_SCIENCE, O_LAST
};
Index: common/nation.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/nation.h,v
retrieving revision 1.35
diff -u -r1.35 nation.h
--- common/nation.h 22 Jan 2005 21:12:10 -0000 1.35
+++ common/nation.h 26 Mar 2005 21:19:16 -0000
@@ -17,6 +17,7 @@
#include "fc_types.h"
#include "terrain.h" /* T_COUNT */
+#include "unittype.h" /* Unit_Type_id */
#define MAX_NUM_TECH_GOALS 10
@@ -92,6 +93,7 @@
/* Items given to this nation at game start. Server only. */
int init_techs[MAX_NUM_TECH_LIST];
int init_buildings[MAX_NUM_BUILDING_LIST];
+ Unit_Type_id init_units[MAX_NUM_UNIT_LIST];
};
struct team {
Index: common/requirements.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/requirements.c,v
retrieving revision 1.6
diff -u -r1.6 requirements.c
--- common/requirements.c 23 Mar 2005 02:07:44 -0000 1.6
+++ common/requirements.c 26 Mar 2005 21:19:21 -0000
@@ -212,7 +212,8 @@
/****************************************************************************
Parse a requirement type and value string into a requrement structure.
Returns REQ_LAST on error. Passing in a NULL type is considered REQ_NONE
- (not an error).
+ (not an error). Pass in a helpful location for this parsing in case
+ we encounter an error.
Pass this some values like "Building", "Factory".
****************************************************************************/
@@ -268,7 +269,7 @@
if (invalid) {
freelog(LOG_ERROR, "Invalid requirement %s | %s | %s | %s",
type, range, survives ? "survives" : "", value);
- exit(EXIT_FAILURE);
+ req.source.type = REQ_LAST;
}
return req;
Index: server/barbarian.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/barbarian.c,v
retrieving revision 1.84
diff -u -r1.84 barbarian.c
--- server/barbarian.c 14 Mar 2005 20:26:25 -0000 1.84
+++ server/barbarian.c 26 Mar 2005 21:19:25 -0000
@@ -201,7 +201,9 @@
struct tile *utile = NULL;
bool alive = TRUE; /* explorer survived */
- if (game.barbarianrate == 0 || (game.year < game.onsetbarbarian)) {
+ if (game.barbarianrate == 0
+ || game.year < game.onsetbarbarian
+ || num_role_units(L_BARBARIAN) != 0) {
unit_list_iterate_safe((ptile)->units, punit) {
wipe_unit(punit);
} unit_list_iterate_safe_end;
Index: server/gamehand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/gamehand.c,v
retrieving revision 1.157
diff -u -r1.157 gamehand.c
--- server/gamehand.c 14 Mar 2005 20:26:25 -0000 1.157
+++ server/gamehand.c 26 Mar 2005 21:19:26 -0000
@@ -141,6 +141,26 @@
}
/****************************************************************************
+ Find a valid position not far from our starting position.
+****************************************************************************/
+static struct tile *find_dispersed_position(struct player *pplayer,
+ struct start_position *p)
+{
+ struct tile *ptile;
+ int x, y;
+
+ do {
+ x = p->tile->x + myrand(2 * game.dispersion + 1) - game.dispersion;
+ y = p->tile->y + myrand(2 * game.dispersion + 1) - game.dispersion;
+ } while (!((ptile = map_pos_to_tile(x, y))
+ && map_get_continent(p->tile) == map_get_continent(ptile)
+ && !is_ocean(map_get_terrain(ptile))
+ && !is_non_allied_unit_tile(ptile, pplayer)));
+
+ return ptile;
+}
+
+/****************************************************************************
Initialize a new game: place the players' units onto the map, etc.
****************************************************************************/
void init_new_game(void)
@@ -225,8 +245,9 @@
/* Place all other units. */
players_iterate(pplayer) {
- int i, x, y;
+ int i;
struct tile *ptile;
+ struct nation_type *nation = get_nation_by_plr(pplayer);
struct start_position p
= map.start_positions[start_pos[pplayer->player_no]];
@@ -235,19 +256,21 @@
continue;
}
+ /* Place global start units */
for (i = 1; i < strlen(game.start_units); i++) {
- do {
- x = p.tile->x + myrand(2 * game.dispersion + 1) - game.dispersion;
- y = p.tile->y + myrand(2 * game.dispersion + 1) - game.dispersion;
- } while (!((ptile = map_pos_to_tile(x, y))
- && map_get_continent(p.tile) == map_get_continent(ptile)
- && !is_ocean(map_get_terrain(ptile))
- && !is_non_allied_unit_tile(ptile, pplayer)));
-
+ ptile = find_dispersed_position(pplayer, &p);
/* Create the unit of an appropriate type. */
place_starting_unit(ptile, pplayer, game.start_units[i]);
}
+
+ /* Place nation specific start units (not role based!) */
+ i = 0;
+ while (nation->init_units[i] != U_LAST && i < MAX_NUM_UNIT_LIST) {
+ ptile = find_dispersed_position(pplayer, &p);
+ create_unit(pplayer, ptile, nation->init_units[i], FALSE, 0, 0);
+ i++;
+ }
} players_iterate_end;
shuffle_players();
Index: server/ruleset.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/ruleset.c,v
retrieving revision 1.235
diff -u -r1.235 ruleset.c
--- server/ruleset.c 24 Mar 2005 16:41:42 -0000 1.235
+++ server/ruleset.c 26 Mar 2005 21:19:27 -0000
@@ -232,6 +232,58 @@
/**************************************************************************
Lookup a prefix.entry string vector in the file and fill in the
+ array, which should hold MAX_NUM_UNIT_LIST items. The output array is
+ either U_LAST terminated or full (contains MAX_NUM_UNIT_LIST
+ items). If the vector is not found and the required parameter is set,
+ we report it as an error, otherwise we just punt.
+**************************************************************************/
+static void lookup_unit_list(struct section_file *file, const char *prefix,
+ const char *entry, int *output,
+ const char *filename, bool required)
+{
+ char **slist;
+ int i, nval;
+
+ /* pre-fill with U_LAST: */
+ for(i = 0; i < MAX_NUM_UNIT_LIST; i++) {
+ output[i] = A_LAST;
+ }
+ slist = secfile_lookup_str_vec(file, &nval, "%s.%s", prefix, entry);
+ if (nval == 0) {
+ if (required) {
+ freelog(LOG_FATAL, "Missing string vector %s.%s (%s)",
+ prefix, entry, filename);
+ exit(EXIT_FAILURE);
+ }
+ return;
+ }
+ if (nval > MAX_NUM_UNIT_LIST) {
+ freelog(LOG_FATAL, "String vector %s.%s too long (%d, max %d) (%s)",
+ prefix, entry, nval, MAX_NUM_UNIT_LIST, filename);
+ exit(EXIT_FAILURE);
+ }
+ if (nval == 1 && strcmp(slist[0], "") == 0) {
+ free(slist);
+ return;
+ }
+ for (i = 0; i < nval; i++) {
+ char *sval = slist[i];
+ Unit_Type_id uid = find_unit_type_by_name(sval);
+
+ if (uid == U_LAST) {
+ freelog(LOG_FATAL, "For %s %s (%d) couldn't match unit \"%s\" (%s)",
+ prefix, entry, i, sval, filename);
+ exit(EXIT_FAILURE);
+ }
+ output[i] = uid;
+ freelog(LOG_DEBUG, "%s.%s,%d %s %d", prefix, entry, i, sval, uid);
+ }
+ free(slist);
+ return;
+}
+
+/**************************************************************************
+ Lookup a prefix.entry string vector in the file and fill in the
array, which should hold MAX_NUM_TECH_LIST items. The output array is
either A_LAST terminated or full (contains MAX_NUM_TECH_LIST
items). All valid entries of the output array are guaranteed to
@@ -1057,40 +1109,37 @@
freelog(LOG_FATAL, "No role=ferryboat units? (%s)", filename);
exit(EXIT_FAILURE);
}
- if(num_role_units(L_HUT)==0) {
- freelog(LOG_FATAL, "No role=hut units? (%s)", filename);
- exit(EXIT_FAILURE);
- }
if(num_role_units(L_FIRSTBUILD)==0) {
freelog(LOG_FATAL, "No role=firstbuild units? (%s)", filename);
exit(EXIT_FAILURE);
}
- if(num_role_units(L_BARBARIAN)==0) {
+ if (num_role_units(L_BARBARIAN) == 0 && game.barbarianrate > 0) {
freelog(LOG_FATAL, "No role=barbarian units? (%s)", filename);
exit(EXIT_FAILURE);
}
- if(num_role_units(L_BARBARIAN_LEADER)==0) {
+ if (num_role_units(L_BARBARIAN_LEADER) == 0 && game.barbarianrate > 0) {
freelog(LOG_FATAL, "No role=barbarian leader units? (%s)", filename);
exit(EXIT_FAILURE);
}
- if(num_role_units(L_BARBARIAN_BUILD)==0) {
+ if (num_role_units(L_BARBARIAN_BUILD) == 0 && game.barbarianrate > 0) {
freelog(LOG_FATAL, "No role=barbarian build units? (%s)", filename);
exit(EXIT_FAILURE);
}
- if(num_role_units(L_BARBARIAN_BOAT)==0) {
+ if (num_role_units(L_BARBARIAN_BOAT) == 0 && game.barbarianrate > 0) {
freelog(LOG_FATAL, "No role=barbarian ship units? (%s)", filename);
exit(EXIT_FAILURE);
+ } else if (num_role_units(L_BARBARIAN_BOAT) > 0) {
+ u = &unit_types[get_role_unit(L_BARBARIAN_BOAT,0)];
+ if(u->move_type != SEA_MOVING) {
+ freelog(LOG_FATAL, "Barbarian boat (%s) needs to be a sea unit (%s)",
+ u->name, filename);
+ exit(EXIT_FAILURE);
+ }
}
- if(num_role_units(L_BARBARIAN_SEA)==0) {
+ if (num_role_units(L_BARBARIAN_SEA) == 0 && game.barbarianrate > 0) {
freelog(LOG_FATAL, "No role=sea raider barbarian units? (%s)", filename);
exit(EXIT_FAILURE);
}
- u = &unit_types[get_role_unit(L_BARBARIAN_BOAT,0)];
- if(u->move_type != SEA_MOVING) {
- freelog(LOG_FATAL, "Barbarian boat (%s) needs to be a sea unit (%s)",
- u->name, filename);
- exit(EXIT_FAILURE);
- }
/* pre-calculate game.rtech.u_partisan
(tech for first partisan unit, or A_LAST */
@@ -2146,6 +2195,8 @@
lookup_tech_list(file, sec[i], "init_techs", pl->init_techs, filename);
lookup_building_list(file, sec[i], "init_buildings", pl->init_buildings,
filename);
+ lookup_unit_list(file, sec[i], "init_units", pl->init_units, filename,
+ FALSE);
/* read "normal" city names */
@@ -2269,7 +2320,7 @@
const char *value
= secfile_lookup_str_default(file, "", "specialist.%s_req%d.value",
name, j);
- struct requirement req = req_from_str(type, range, survives, value);
+ struct requirement req = req_from_str(type, range, survives, value);
if (req.source.type == REQ_LAST) {
freelog(LOG_ERROR,
Index: server/unittools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unittools.c,v
retrieving revision 1.330
diff -u -r1.330 unittools.c
--- server/unittools.c 24 Mar 2005 17:48:49 -0000 1.330
+++ server/unittools.c 26 Mar 2005 21:19:29 -0000
@@ -2382,7 +2382,11 @@
hut_get_tech(punit);
break;
case 8: case 9:
- hut_get_mercenaries(punit);
+ if (num_role_units(L_HUT) != 0) {
+ hut_get_mercenaries(punit);
+ } else {
+ hut_get_gold(punit, 25);
+ }
break;
case 10:
ok = hut_get_barbarians(punit);
Index: utility/shared.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/utility/shared.h,v
retrieving revision 1.141
diff -u -r1.141 shared.h
--- utility/shared.h 26 Feb 2005 18:27:19 -0000 1.141
+++ utility/shared.h 26 Mar 2005 21:19:29 -0000
@@ -55,24 +55,8 @@
#define fc__attribute(x)
#endif
-
-/* Note: the capability string is now in capstr.c --dwp */
-/* Version stuff is now in version.h --dwp */
-
-#define BUG_EMAIL_ADDRESS "bugs@xxxxxxxxxxx"
-#define WEBSITE_URL "http://www.freeciv.org/"
-
-/* MAX_NUM_PLAYERS + MAX_NUM_BARBARIANS <= 32 !!!! */
-#define MAX_NUM_PLAYERS 30
-#define MAX_NUM_BARBARIANS 2
-#define MAX_NUM_CONNECTIONS (2 * (MAX_NUM_PLAYERS + MAX_NUM_BARBARIANS))
-#define MAX_NUM_ITEMS 200 /* eg, unit_types */
-#define MAX_NUM_TECH_LIST 10
-#define MAX_NUM_BUILDING_LIST 10
#define MAX_LEN_NAME 32
#define MAX_LEN_ADDR 256 /* see also MAXHOSTNAMELEN and RFC 1123 2.1 */
-#define MAX_LEN_VET_SHORT_NAME 8
-#define MAX_VET_LEVELS 10
#define MAX_LEN_PATH 4095
/* Use FC_INFINITY to denote that a certain event will never occur or
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Freeciv-Dev] (PR#12667) A few modpack fixes,
Per I. Mathisen <=
|
|