Complete.Org: Mailing Lists: Archives: freeciv-dev: January 2001:
[Freeciv-Dev] Citypref patch
Home

[Freeciv-Dev] Citypref patch

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: freeciv-dev@xxxxxxxxxxx
Subject: [Freeciv-Dev] Citypref patch
From: Andrew <andrew@xxxxxxxxxxx>
Date: Sat, 20 Jan 2001 19:47:13 -0500
Reply-to: andrew@xxxxxxxxxxx

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;
 }





[Prev in Thread] Current Thread [Next in Thread]