[Freeciv-Dev] Citypref patch
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
All:
Civ2 had a feature whereby a player could create a text file named
"citypref.txt" listing the default order that all cities should build
improvements.
The same feature can be added to freeciv by adding a new function to
server/cityturn.c. I have also included a short file for the doc
directory. The diff file follows. (diff'd against version 1.11.4).
For your consideration,
Andrew Howlett.
diff -Nr -u freeciv-1.11.4_orig/doc/citypref_README.txt
freeciv-1.11.4/doc/citypref_README.txt
--- freeciv-1.11.4_orig/doc/citypref_README.txt Wed Dec 31 19:00:00 1969
+++ freeciv-1.11.4/doc/citypref_README.txt Sat Jan 20 19:09:54 2001
@@ -0,0 +1,52 @@
+-----------------------------------------
+citypref patch
+
+Jan 2001, andrew@xxxxxxxxxxx
+to be applied to freeciv v1.11.4
+-----------------------------------------
+
+AIM
+===
+
+The aim of the citypref patch is to implement the citypref.txt feature
+found in civ2. citypref.txt is a file that defines the default order
+in which a city will build improvements.
+
+REQUIREMENTS
+============
+
+This file patches freeciv 1.11.4 code.
+
+HOW TO USE THE FREECIV CITYPREF FEATURE
+=======================================
+
+1. create a global worklist named "citypref"
+
+2. if a city does not have its own worklist,
+ then the citypref worklist applies to that city.
+
+3. to disable citypref temporarily, just rename
+ the worklist from citypref to something else
+
+HOW IT WORKS
+============
+
+1. At the end/beginning of a year, the server updates production
+ at the player's cities. If a city has completed production,
+ then the server calls the worklist_change_build_target
+ function to change the production target in accordance with
+ the city's worklist. If the function changes production, then
+ it returns non-zero. If the city has no worklist, or there
+ are no valid worklist entries, then it returns zero.
+
+2. worklist_change_build_target returns at two points, at
+ both points I insert a call to citypref_change_build_target
+
+3. the new function citypref_change_build_target looks through
+ the player->worklists array for a worklist named "citypref".
+ If no "citypref" worklist exists, then the function returns
+ zero. If citypref exists, then the function does almost
+ exactly the same thing as worklist_change_build_target, except
+ citypref_change_build_target uses the citypref worklist for
+ new targets.
+
diff -Nr -u freeciv-1.11.4_orig/server/cityturn.c
freeciv-1.11.4/server/cityturn.c
--- freeciv-1.11.4_orig/server/cityturn.c Thu Jul 6 11:48:17 2000
+++ freeciv-1.11.4/server/cityturn.c Sat Jan 20 15:54:02 2001
@@ -1012,6 +1012,110 @@
}
/**************************************************************************
+
+ Implement citypref feature:
+
+ If a global worklist named "citypref" exists, then use that worklist
+ and change build target. Return 0 if no targets are available,
otherwise
+ return non-zero. Makes no changes to the citypref worklist
+**************************************************************************/
+
+static int citypref_change_build_target (struct player *pplayer, struct
city *pcity)
+{
+ int success = 0;
+ int i;
+ int citypref_idx = -1;
+
+ /* which global worklist is named "citypref"? */
+
+ freelog(LOG_DEBUG, "citypref: entered
citypref_change_build_target");
+
+ for (i=0; i<=MAX_NUM_WORKLISTS; i++) {
+ freelog(LOG_DEBUG, "citypref: looking at worklist %s",
pplayer->worklists[i].name);
+ if (!strcmp(pplayer->worklists[i].name,"citypref"))
citypref_idx = i;
+ }
+
+ /* if none named citypref, then return 0 */
+
+ if (citypref_idx == -1) return 0;
+
+ /* get a valid target from the citypref worklist
+ use the same algorithm as worklist_change_build_target,
+ but don't delete locally invalid entries from the
global
+ citypref worklist */
+
+ i = 0;
+ while (1) {
+ int target, is_unit;
+
+ /* What's the next item in the worklist? */
+ if (!worklist_peek_ith( &pplayer->worklists[citypref_idx], &target,
&is_unit, i))
+ /* Nothing more in the worklist. Ah, well. */
+ break;
+
+ i++;
+
+ /* Sanity checks. First, target is a unit but the city can't build
it */
+ if (is_unit && !can_build_unit(pcity, target)) {
+ int new_target = unit_upgrades_to(pcity, target);
+
+ /* Maybe we can just upgrade the target to what the city /can/
build. */
+ if (new_target == target) {
+ /* No upgrade available. Advise the
player and proceed to next item in the worklist */
+ notify_player_ex(pplayer, pcity->x,
pcity->y, E_CITY_CANTBUILD,
+
_("Game: %s cannot build %s from the citypref worklist. "),
+
pcity->name, get_unit_type(target)->name);
+ continue;
+ } else {
+ /* Yes, we can go after new_target
instead. */
+ notify_player_ex(pplayer, pcity->x,
pcity->y, E_WORKLIST,
+
_("Game: Production of %s is upgraded to %s in %s."),
+
get_unit_type(target)->name, get_unit_type(new_target)->name,
+
pcity->name);
+ target = new_target;
+ }
+ } else if (!is_unit && !can_build_improvement(pcity, target)) {
+ int new_target = improvement_upgrades_to(pcity, target);
+
+ /* Maybe this improvement has been obsoleted by something that we
can build. */
+ if (new_target == target) {
+ /* No. Warn the player and move to next
id in worklist */
+
+ /* Does the city already have that
improvement? */
+ if (city_got_building(pcity, target)) {
+ freelog(LOG_DEBUG, "citypref: %s
already has %s", pcity->name,
+
get_impr_name_ex(pcity, target));
+ } else {
+ freelog(LOG_DEBUG, "citypref: %s
can't build %s", pcity-> name,
+
get_impr_name_ex(pcity, target));
+ notify_player_ex(pplayer,
pcity->x, pcity->y, E_CITY_CANTBUILD,
+
_("Game: %s can't build %s from the citypref worklist; "),
+
pcity->name, get_impr_name_ex(pcity, target));
+ }
+ continue;
+ } else {
+ /* Hey, we can upgrade the improvement!
*/
+ notify_player_ex(pplayer, pcity->x,
pcity->y, E_WORKLIST,
+
_("Game: Production of %s is upgraded to %s in %s."),
+
get_impr_name_ex(pcity, target), get_impr_name_ex(pcity, new_target),
+
pcity->name);
+ target = new_target;
+ }
+ }
+
+ /* All okay. Switch targets. */
+ change_build_target(pplayer, pcity, target, is_unit, E_WORKLIST);
+
+ success = 1;
+ break;
+ }
+
+ freelog(LOG_DEBUG, "Exiting citypref_change_build_target");
+ return success;
+
+}
+
+/**************************************************************************
Examine the worklist and change the build target. Return 0 if no
targets are available to change to. Otherwise return non-zero. Has
the side-effect of removing from the worklist any no-longer-available
@@ -1024,7 +1128,7 @@
if (worklist_is_empty(pcity->worklist))
/* Nothing in the worklist; bail now. */
- return 0;
+ return citypref_change_build_target(pplayer, pcity);
i = 0;
while (1) {
@@ -1141,6 +1245,8 @@
_("Game: %s's worklist is now empty."),
pcity->name);
}
+
+ if (!success) success = citypref_change_build_target(pplayer,
pcity);
return success;
}
- [Freeciv-Dev] Citypref patch,
Andrew <=
|
|