Complete.Org: Mailing Lists: Archives: freeciv-dev: May 2005:
[Freeciv-Dev] (PR#8759) effects to give bonuses to specialists
Home

[Freeciv-Dev] (PR#8759) effects to give bonuses to specialists

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To:
Subject: [Freeciv-Dev] (PR#8759) effects to give bonuses to specialists
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Tue, 10 May 2005 11:50:51 -0700
Reply-to: bugs@xxxxxxxxxxx

<URL: http://bugs.freeciv.org/Ticket/Display.html?id=8759 >

And, here is the patch.

* Specialist reqs are added to the requirement structure.  They apply
only at local range.

* Requirements and effects take a specialist target.

* The current specialist->bonus[] values are removed.

* A new effect type, EFT_SPECIALIST_OUTPUT.  This, simply, tells the
amount of output a specialist provides.  It is called by passing the
output type, specialist type, and city as targets.

* cities.ruleset and effects.ruleset are updated for the changes.

* ruleset.c and packhand.c and packets.def are updated.

The ugly bit is in the city.h and specialist.h interface.  A new
function get_specialist_output is added to specialist.h that wraps the
effect function.  However this has to do a lookup on the struct pointers
for the specialist and the output type.  It would be much easier if we
just worked directly with struct values from the start (particularly in
the _iterate macros).  This basically applies to all ruleset items.

-jason

Index: ai/aicity.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aicity.c,v
retrieving revision 1.223
diff -u -r1.223 aicity.c
--- ai/aicity.c 10 May 2005 17:27:09 -0000      1.223
+++ ai/aicity.c 10 May 2005 18:48:16 -0000
@@ -98,7 +98,7 @@
   int providers = 0;
 
   specialist_type_iterate(i) {
-    if (get_specialist(i)->bonus[O_LUXURY] >= HAPPY_COST) {
+    if (get_specialist_output(pcity, i, O_LUXURY) >= HAPPY_COST) {
       providers += pcity->specialists[i];
     }
   } specialist_type_iterate_end;
@@ -279,7 +279,7 @@
     bool useful;
 
     if (is_effect_disabled(pplayer, pcity, pimpr,
-                          NULL, NULL, NULL,
+                          NULL, NULL, NULL, NULL,
                           peffect)) {
       CITY_LOG(LOG_DEBUG, pcity, "%s has a disabled effect: %s", 
                get_improvement_name(id), effect_type_name(peffect->type));
@@ -296,7 +296,8 @@
        mypreq = preq;
         continue;
       }
-      if (!is_req_active(pplayer, pcity, pimpr, NULL, NULL, NULL, preq)) {
+      if (!is_req_active(pplayer, pcity, pimpr, NULL, NULL, NULL, NULL,
+                        preq)) {
        useful = FALSE;
        break;
       }
@@ -323,6 +324,7 @@
       case EFT_OUTPUT_INC_TILE:
       case EFT_OUTPUT_PER_TILE:
       case EFT_OUTPUT_WASTE_PCT:
+      case EFT_SPECIALIST_OUTPUT:
          break;
 
       case EFT_SLOW_DOWN_TIMELINE:
Index: client/helpdata.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/helpdata.c,v
retrieving revision 1.114
diff -u -r1.114 helpdata.c
--- client/helpdata.c   7 May 2005 18:58:02 -0000       1.114
+++ client/helpdata.c   10 May 2005 18:48:17 -0000
@@ -198,6 +198,10 @@
     cat_snprintf(buf, bufsz, _("Applies only to %s.\n\n"),
                 get_output_name(req->source.value.outputtype));
     return;
+  case REQ_SPECIALIST:
+    cat_snprintf(buf, bufsz, _("Applies only to %s.\n\n"),
+                _(get_specialist(req->source.value.specialist)->name));
+    return;
   case REQ_MINSIZE:
     cat_snprintf(buf, bufsz, _("Requires a minimum size of %d.\n\n"),
                 req->source.value.minsize);
Index: client/packhand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/packhand.c,v
retrieving revision 1.510
diff -u -r1.510 packhand.c
--- client/packhand.c   10 May 2005 17:01:23 -0000      1.510
+++ client/packhand.c   10 May 2005 18:48:17 -0000
@@ -2431,14 +2431,10 @@
   DEFAULT_SPECIALIST = packet->default_specialist;
   specialist_type_iterate(sp) {
     struct specialist *s = get_specialist(sp);
-    int *bonus = s->bonus;
     int j;
 
     sz_strlcpy(s->name, packet->specialist_name[sp]);
     sz_strlcpy(s->short_name, packet->specialist_short_name[sp]);
-    output_type_iterate(o) {
-      bonus[o] = packet->specialist_bonus[sp * O_COUNT + o];
-    } output_type_iterate_end;
 
     for (j = 0; j < MAX_NUM_REQS; j++) {
       int index = sp * MAX_NUM_REQS + j;
Index: common/city.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/city.c,v
retrieving revision 1.344
diff -u -r1.344 city.c
--- common/city.c       10 May 2005 17:01:23 -0000      1.344
+++ common/city.c       10 May 2005 18:48:18 -0000
@@ -254,6 +254,18 @@
   return _(output_types[output].name);
 }
 
+/****************************************************************************
+  Return the output type for this index.
+****************************************************************************/
+struct output_type *get_output_type(Output_type_id output)
+{
+  if (output < 0 || output >= O_LAST) {
+    assert(0);
+    return NULL;
+  }
+  return &output_types[output];
+}
+
 /**************************************************************************
   Find the output type for this output identifier.
 **************************************************************************/
@@ -397,7 +409,7 @@
       break;
     }
     if (!is_req_active(city_owner(pcity), pcity, NULL,
-                      pcity->tile, NULL, NULL,
+                      pcity->tile, NULL, NULL, NULL,
                       &building->req[i])) {
       return FALSE;
     }
@@ -445,7 +457,7 @@
     }
     if (is_req_unchanging(&building->req[r])
        && !is_req_active(city_owner(pcity), pcity, NULL,
-                         pcity->tile, NULL, NULL,
+                         pcity->tile, NULL, NULL, NULL,
                          &building->req[r])) {
       return FALSE;
     }
@@ -523,7 +535,8 @@
 bool city_can_use_specialist(const struct city *pcity,
                             Specialist_type_id type)
 {
-  return are_reqs_active(city_owner(pcity), pcity, NULL, NULL, NULL, NULL,
+  return are_reqs_active(city_owner(pcity), pcity, NULL,
+                        NULL, NULL, NULL, NULL,
                         get_specialist(type)->req, MAX_NUM_REQS);
 }
 
@@ -1112,7 +1125,7 @@
 
   while ((replace = city_styles[prev].replaced_by) != -1) {
     prev = replace;
-    if (are_reqs_active(plr, NULL, NULL, NULL, NULL, NULL,
+    if (are_reqs_active(plr, NULL, NULL, NULL, NULL, NULL, NULL,
                        city_styles[replace].req, MAX_NUM_REQS)) {
       style = replace;
     }
@@ -1546,11 +1559,12 @@
                                         int *output)
 {
   specialist_type_iterate(sp) {
-    int *bonus = get_specialist(sp)->bonus;
     int count = pcity->specialists[sp];
 
     output_type_iterate(stat) {
-      output[stat] += count * bonus[stat];
+      int amount = get_specialist_output(pcity, sp, stat);
+
+      output[stat] += count * amount;
     } output_type_iterate_end;
   } specialist_type_iterate_end;
 }
@@ -2266,13 +2280,15 @@
                                   const struct city *pcity)
 {
   int best = DEFAULT_SPECIALIST;
-  int val = get_specialist(best)->bonus[otype];
+  int val = get_specialist_output(pcity, best, otype);
 
   specialist_type_iterate(i) {
     if (!pcity || city_can_use_specialist(pcity, i)) {
-      if (get_specialist(i)->bonus[otype] > val) {
+      int val2 = get_specialist_output(pcity, i, otype);
+
+      if (val2 > val) {
        best = i;
-       val = get_specialist(i)->bonus[otype];
+       val = val2;
       }
     }
   } specialist_type_iterate_end;
Index: common/city.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/city.h,v
retrieving revision 1.212
diff -u -r1.212 city.h
--- common/city.h       10 May 2005 17:01:23 -0000      1.212
+++ common/city.h       10 May 2005 18:48:18 -0000
@@ -369,6 +369,7 @@
 
 const char *get_output_identifier(Output_type_id output);
 const char *get_output_name(Output_type_id output);
+struct output_type *get_output_type(Output_type_id output);
 Output_type_id find_output_type_by_identifier(const char *id);
 
 /* properties */
Index: common/effects.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/effects.c,v
retrieving revision 1.41
diff -u -r1.41 effects.c
--- common/effects.c    8 May 2005 06:19:04 -0000       1.41
+++ common/effects.c    10 May 2005 18:48:18 -0000
@@ -43,6 +43,7 @@
   "Capital_City",
   "Enable_Nuke",
   "Enable_Space",
+  "Specialist_Output",
   "Output_Bonus",
   "Output_Bonus_2",
   "Output_Add_Tile",
@@ -541,11 +542,13 @@
                        const struct tile *target_tile,
                        const struct unit *target_unit,
                        const struct output_type *target_output,
+                       const struct specialist *target_specialist,
                        const struct effect *peffect)
 {
   requirement_list_iterate(peffect->nreqs, preq) {
     if (is_req_active(target_player, target_city, target_building,
                      target_tile, target_unit, target_output,
+                     target_specialist,
                      preq)) {
       return TRUE;
     }
@@ -564,11 +567,13 @@
                              const struct tile *target_tile,
                              const struct unit *target_unit,
                              const struct output_type *target_output,
+                             const struct specialist *target_specialist,
                              const struct effect *peffect)
 {
   requirement_list_iterate(peffect->reqs, preq) {
     if (!is_req_active(target_player, target_city, target_building,
                       target_tile, target_unit, target_output,
+                      target_specialist,
                       preq)) {
       return FALSE;
     }
@@ -591,13 +596,16 @@
                             const struct tile *target_tile,
                             const struct unit *target_unit,
                             const struct output_type *target_output,
+                            const struct specialist *target_specialist,
                             const struct effect *peffect)
 {
   return is_effect_enabled(target_player, target_city, target_building,
                           target_tile, target_unit, target_output,
+                          target_specialist,
                           peffect)
     && !is_effect_disabled(target_player, target_city, target_building,
                           target_tile, target_unit, target_output,
+                          target_specialist,
                           peffect);
 }
 
@@ -619,10 +627,12 @@
                      const struct tile *target_tile,
                      const struct unit *target_unit,
                      const struct output_type *target_output,
+                     const struct specialist *target_specialist,
                      Impr_type_id source, const struct effect *peffect)
 {
   if (is_effect_disabled(target_player, target_city, target_building,
                         target_tile, target_unit, target_output,
+                        target_specialist,
                         peffect)) {
     return FALSE;
   }
@@ -633,6 +643,7 @@
     }
     if (!is_req_active(target_player, target_city, target_building,
                       target_tile, target_unit, target_output,
+                      target_specialist,
                       preq)) {
       return FALSE;
     }
@@ -664,7 +675,8 @@
      * the building is its own target - but whether this is actually
      * checked depends on the range of the effect. */
     if (!is_effect_disabled(city_owner(pcity), pcity,
-                           get_improvement_type(building), NULL, NULL, NULL,
+                           get_improvement_type(building),
+                           NULL, NULL, NULL, NULL,
                            peffect)) {
       return FALSE;
     }
@@ -691,6 +703,7 @@
                                    const struct tile *target_tile,
                                    const struct unit *target_unit,
                                    const struct output_type *target_output,
+                                   const struct specialist *target_specialist,
                                    enum effect_type effect_type)
 {
   int bonus = 0;
@@ -700,6 +713,7 @@
     /* For each effect, see if it is active. */
     if (is_effect_active(target_player, target_city, target_building,
                         target_tile, target_unit, target_output,
+                        target_specialist,
                         peffect)) {
       /* And if so add on the value. */
       bonus += peffect->value;
@@ -723,7 +737,7 @@
   }
 
   return get_target_bonus_effects(NULL,
-                                 NULL, NULL, NULL, NULL, NULL, NULL,
+                                 NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                  effect_type);
 }
 
@@ -738,7 +752,8 @@
   }
 
   return get_target_bonus_effects(NULL,
-                                 pplayer, NULL, NULL, NULL, NULL, NULL,
+                                 pplayer, NULL, NULL,
+                                 NULL, NULL, NULL, NULL,
                                  effect_type);
 }
 
@@ -753,7 +768,24 @@
 
   return get_target_bonus_effects(NULL,
                                  city_owner(pcity), pcity, NULL,
-                                 NULL, NULL, NULL,
+                                 NULL, NULL, NULL, NULL,
+                                 effect_type);
+}
+
+/**************************************************************************
+  Returns the effect bonus of a specialist in a city.
+**************************************************************************/
+int get_city_specialist_output_bonus(const struct city *pcity,
+                                    const struct specialist *pspecialist,
+                                    const struct output_type *poutput,
+                                    enum effect_type effect_type)
+{
+  assert(pcity != NULL);
+  assert(pspecialist != NULL);
+  assert(poutput != NULL);
+  return get_target_bonus_effects(NULL,
+                                 city_owner(pcity), pcity, NULL,
+                                 NULL, NULL, poutput, pspecialist,
                                  effect_type);
 }
 
@@ -774,7 +806,7 @@
   assert(pcity != NULL);
   return get_target_bonus_effects(NULL,
                                  city_owner(pcity), pcity, NULL,
-                                 ptile, NULL, poutput,
+                                 ptile, NULL, poutput, NULL,
                                  effect_type);
 }
 
@@ -788,7 +820,7 @@
   return get_target_bonus_effects(NULL,
                                  city_owner(pcity), pcity,
                                  get_improvement_type(id),
-                                 NULL, NULL, NULL,
+                                 NULL, NULL, NULL, NULL,
                                  effect_type);
 }
 
@@ -800,7 +832,7 @@
   assert(punit != NULL);
   return get_target_bonus_effects(NULL,
                                  unit_owner(punit), NULL, NULL,
-                                 NULL, punit, NULL,
+                                 NULL, punit, NULL, NULL,
                                  effect_type);
 }
 
@@ -817,7 +849,7 @@
   assert(pplayer != NULL);
   return get_target_bonus_effects(plist,
                                  pplayer, NULL, NULL,
-                                 NULL, NULL, NULL,
+                                 NULL, NULL, NULL, NULL,
                                  effect_type);
 }
 
@@ -835,7 +867,7 @@
   assert(pcity != NULL);
   return get_target_bonus_effects(plist,
                                  city_owner(pcity), pcity, NULL,
-                                 NULL, NULL, poutput,
+                                 NULL, NULL, poutput, NULL,
                                  effect_type);
 }
 
@@ -866,7 +898,7 @@
          continue;
        }
        if (is_effect_useful(city_owner(pcity), pcity, building,
-                            NULL, NULL, NULL,
+                            NULL, NULL, NULL, NULL,
                             id, peffect)) {
          power += peffect->value;
        }
Index: common/effects.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/effects.h,v
retrieving revision 1.25
diff -u -r1.25 effects.h
--- common/effects.h    7 May 2005 18:58:02 -0000       1.25
+++ common/effects.h    10 May 2005 18:48:18 -0000
@@ -30,6 +30,7 @@
   EFT_CAPITAL_CITY,
   EFT_ENABLE_NUKE,
   EFT_ENABLE_SPACE,
+  EFT_SPECIALIST_OUTPUT,
   EFT_OUTPUT_BONUS,
   EFT_OUTPUT_BONUS_2,
   EFT_OUTPUT_ADD_TILE,
@@ -160,6 +161,7 @@
                      const struct tile *target_tile,
                      const struct unit *target_unit,
                      const struct output_type *target_output,
+                     const struct specialist *target_specialist,
                      Impr_type_id source, const struct effect *effect);
 
 bool is_building_replaced(const struct city *pcity, Impr_type_id building);
@@ -168,6 +170,10 @@
 int get_world_bonus(enum effect_type effect_type);
 int get_player_bonus(const struct player *plr, enum effect_type effect_type);
 int get_city_bonus(const struct city *pcity, enum effect_type effect_type);
+int get_city_specialist_output_bonus(const struct city *pcity,
+                                    const struct specialist *pspecialist,
+                                    const struct output_type *poutput,
+                                    enum effect_type effect_type);
 int get_city_tile_output_bonus(const struct city *pcity,
                               const struct tile *ptile,
                               const struct output_type *poutput,
@@ -184,6 +190,7 @@
                        const struct tile *target_tile,
                        const struct unit *target_unit,
                        const struct output_type *target_output,
+                       const struct specialist *target_specialist,
                        const struct effect *peffect);
 
 int get_player_bonus_effects(struct effect_list *plist,
Index: common/fc_types.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/fc_types.h,v
retrieving revision 1.24
diff -u -r1.24 fc_types.h
--- common/fc_types.h   5 May 2005 18:32:49 -0000       1.24
+++ common/fc_types.h   10 May 2005 18:48:18 -0000
@@ -70,6 +70,7 @@
 struct unit;
 struct impr_type;
 struct output_type;
+struct specialist;
 
 /* Changing these will break network compatibility. */
 #define SP_MAX 20
Index: common/government.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/government.c,v
retrieving revision 1.57
diff -u -r1.57 government.c
--- common/government.c 7 May 2005 18:58:02 -0000       1.57
+++ common/government.c 10 May 2005 18:48:18 -0000
@@ -148,7 +148,7 @@
     return TRUE;
   }
 
-  return are_reqs_active(pplayer, NULL, NULL, NULL, NULL, NULL,
+  return are_reqs_active(pplayer, NULL, NULL, NULL, NULL, NULL, NULL,
                         gov->req, MAX_NUM_REQS);
 }
 
Index: common/improvement.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/improvement.c,v
retrieving revision 1.61
diff -u -r1.61 improvement.c
--- common/improvement.c        7 May 2005 18:58:03 -0000       1.61
+++ common/improvement.c        10 May 2005 18:48:18 -0000
@@ -305,7 +305,7 @@
       break;
     }
     if (impr->req[i].range >= REQ_RANGE_PLAYER
-       && !is_req_active(p, NULL, NULL, NULL, NULL, NULL,
+       && !is_req_active(p, NULL, NULL, NULL, NULL, NULL, NULL,
                          &impr->req[i])) {
       return FALSE;
     }
@@ -390,7 +390,7 @@
     }
     if (building->req[r].range >= REQ_RANGE_PLAYER
        && is_req_unchanging(&building->req[r])
-       && !is_req_active(p, NULL, NULL, NULL, NULL, NULL,
+       && !is_req_active(p, NULL, NULL, NULL, NULL, NULL, NULL,
                          &building->req[r])) {
       return FALSE;
     }
Index: common/packets.def
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/packets.def,v
retrieving revision 1.121
diff -u -r1.121 packets.def
--- common/packets.def  10 May 2005 17:27:09 -0000      1.121
+++ common/packets.def  10 May 2005 18:48:18 -0000
@@ -1051,7 +1051,6 @@
   UINT8 req_array_size; # Another hack to get around limitations of packgen
   STRING specialist_name[SP_MAX:num_specialist_types][MAX_LEN_NAME];
   STRING specialist_short_name[SP_MAX:num_specialist_types][MAX_LEN_NAME];
-  UINT8 specialist_bonus[SP_MAX * O_MAX:bonus_array_size];
   UINT8 specialist_req_type[SP_MAX * MAX_NUM_REQS:req_array_size];
   UINT8 specialist_req_range[SP_MAX * MAX_NUM_REQS:req_array_size];
   UINT32 specialist_req_value[SP_MAX * MAX_NUM_REQS:req_array_size];
Index: common/requirements.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/requirements.c,v
retrieving revision 1.22
diff -u -r1.22 requirements.c
--- common/requirements.c       7 May 2005 18:58:03 -0000       1.22
+++ common/requirements.c       10 May 2005 18:48:19 -0000
@@ -39,6 +39,7 @@
   "UnitType",
   "UnitFlag",
   "OutputType",
+  "Specialist",
   "MinSize"
 };
 
@@ -157,6 +158,11 @@
       return source;
     }
     break;
+  case REQ_SPECIALIST:
+    source.value.specialist = find_specialist_by_name(value);
+    if (source.value.specialist != SP_MAX) {
+      return source;
+    }
   case REQ_MINSIZE:
     source.value.minsize = atoi(value);
     if (source.value.minsize > 0) {
@@ -212,6 +218,9 @@
   case REQ_OUTPUTTYPE:
     source.value.outputtype = value;
     return source;
+  case REQ_SPECIALIST:
+    source.value.specialist = value;
+    return source;
   case REQ_MINSIZE:
     source.value.minsize = value;
     return source;
@@ -264,6 +273,9 @@
   case REQ_OUTPUTTYPE:
     *value = source->value.outputtype;
     return;
+  case REQ_SPECIALIST:
+    *value = source->value.specialist;
+    return;
   case REQ_MINSIZE:
     *value = source->value.minsize;
     return;
@@ -305,6 +317,7 @@
     case REQ_UNITTYPE:
     case REQ_UNITFLAG:
     case REQ_OUTPUTTYPE:
+    case REQ_SPECIALIST:
       req.range = REQ_RANGE_LOCAL;
       break;
     case REQ_MINSIZE:
@@ -349,9 +362,8 @@
     break;
   case REQ_UNITTYPE:
   case REQ_UNITFLAG:
-    invalid = (req.range != REQ_RANGE_LOCAL);
-    break;
   case REQ_OUTPUTTYPE:
+  case REQ_SPECIALIST:
     invalid = (req.range != REQ_RANGE_LOCAL);
     break;
   case REQ_NONE:
@@ -719,6 +731,7 @@
                   const struct tile *target_tile,
                   const struct unit *target_unit,
                   const struct output_type *target_output,
+                  const struct specialist *target_specialist,
                   const struct requirement *req)
 {
   /* Note the target may actually not exist.  In particular, effects that
@@ -766,6 +779,9 @@
   case REQ_OUTPUTTYPE:
     return (target_output
            && target_output->index == req->source.value.outputtype);
+  case REQ_SPECIALIST:
+    return (target_specialist
+           && target_specialist->index == req->source.value.specialist);
   case REQ_MINSIZE:
     return target_city && target_city->size >= req->source.value.minsize;
   case REQ_LAST:
@@ -796,6 +812,7 @@
                     const struct tile *target_tile,
                     const struct unit *target_unit,
                     const struct output_type *target_output,
+                    const struct specialist *target_specialist,
                     const struct requirement *reqs, int num_reqs)
 {
   int i;
@@ -805,6 +822,7 @@
       break; /* Short-circuit any more checks. */
     } else if (!is_req_active(target_player, target_city, target_building,
                              target_tile, target_unit, target_output,
+                             target_specialist,
                              &reqs[i])) {
       return FALSE;
     }
@@ -829,6 +847,7 @@
   case REQ_NATION:
   case REQ_NONE:
   case REQ_OUTPUTTYPE:
+  case REQ_SPECIALIST: /* Only so long as it's at local range only */
     return TRUE;
   case REQ_TECH:
   case REQ_GOV:
@@ -882,6 +901,8 @@
     return psource1->value.unitflag == psource2->value.unitflag;
   case REQ_OUTPUTTYPE:
     return psource1->value.outputtype == psource2->value.outputtype;
+  case REQ_SPECIALIST:
+    return psource1->value.specialist == psource2->value.specialist;
   case REQ_MINSIZE:
     return psource1->value.minsize == psource2->value.minsize;
   case REQ_LAST:
@@ -931,6 +952,9 @@
   case REQ_OUTPUTTYPE:
     mystrlcat(buf, get_output_name(psource->value.outputtype), bufsz);
     break;
+  case REQ_SPECIALIST:
+    mystrlcat(buf, get_specialist(psource->value.specialist)->name, bufsz);
+    break;
   case REQ_MINSIZE:
     cat_snprintf(buf, bufsz, _("Size %d"),
                 psource->value.minsize);
Index: common/requirements.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/requirements.h,v
retrieving revision 1.16
diff -u -r1.16 requirements.h
--- common/requirements.h       7 May 2005 18:58:03 -0000       1.16
+++ common/requirements.h       10 May 2005 18:48:19 -0000
@@ -31,6 +31,7 @@
   REQ_UNITTYPE,
   REQ_UNITFLAG,
   REQ_OUTPUTTYPE,
+  REQ_SPECIALIST,
   REQ_MINSIZE, /* Minimum size: at city range means city size */
   REQ_LAST
 };
@@ -61,6 +62,7 @@
     Unit_type_id unittype;              /* source unittype */
     enum unit_flag_id unitflag;         /* source unit flag */
     Output_type_id outputtype;          /* source output type */
+    Specialist_type_id specialist;      /* specialist type */
     int minsize;                        /* source minsize type */
   } value;                              /* source value */
 };
@@ -109,6 +111,7 @@
                   const struct tile *target_tile,
                   const struct unit *target_unit,
                   const struct output_type *target_output,
+                  const struct specialist *target_specialist,
                   const struct requirement *req);
 bool are_reqs_active(const struct player *target_player,
                     const struct city *target_city,
@@ -116,6 +119,7 @@
                     const struct tile *target_tile,
                     const struct unit *target_unit,
                     const struct output_type *target_output,
+                    const struct specialist *target_specialist,
                     const struct requirement *reqs, int num_reqs);
 
 bool is_req_unchanging(const struct requirement *req);
Index: common/specialist.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/specialist.c,v
retrieving revision 1.1
diff -u -r1.1 specialist.c
--- common/specialist.c 10 May 2005 17:01:24 -0000      1.1
+++ common/specialist.c 10 May 2005 18:48:19 -0000
@@ -15,6 +15,8 @@
 #include <config.h>
 #endif
 
+#include "city.h"
+#include "effects.h"
 #include "specialist.h"
 
 struct specialist specialists[SP_MAX];
@@ -42,6 +44,21 @@
 }
 
 /****************************************************************************
+  Return the specialist type with the given (untranslated!) name, or SP_MAX
+  if none is found.
+****************************************************************************/
+Specialist_type_id find_specialist_by_name(const char *name)
+{
+  specialist_type_iterate(sp) {
+    if (strcmp(specialists[sp].name, name) == 0) {
+      return sp;
+    }
+  } specialist_type_iterate_end;
+
+  return SP_MAX;
+}
+
+/****************************************************************************
   Return a string showing the number of specialists in the array.
 
   For instance with a city with (0,3,1) specialists call
@@ -64,3 +81,16 @@
 
   return buf;
 }
+
+/****************************************************************************
+  Return the output for the specialist type with this output type.
+****************************************************************************/
+int get_specialist_output(const struct city *pcity,
+                         Specialist_type_id sp, Output_type_id otype)
+{
+  struct specialist *pspecialist = &specialists[sp];
+  struct output_type *poutput = get_output_type(otype);
+
+  return get_city_specialist_output_bonus(pcity, pspecialist, poutput,
+                                         EFT_SPECIALIST_OUTPUT);
+}
Index: common/specialist.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/specialist.h,v
retrieving revision 1.1
diff -u -r1.1 specialist.h
--- common/specialist.h 10 May 2005 17:01:24 -0000      1.1
+++ common/specialist.h 10 May 2005 18:48:19 -0000
@@ -23,7 +23,6 @@
   int index;
   char name[MAX_LEN_NAME];
   char short_name[MAX_LEN_NAME];
-  int bonus[O_MAX];
   struct requirement req[MAX_NUM_REQS];
 };
 
@@ -36,9 +35,13 @@
 
 void specialists_init(void);
 struct specialist *get_specialist(Specialist_type_id spec);
+Specialist_type_id find_specialist_by_name(const char *name);
 
 const char *specialists_string(const int *specialists);
 
+int get_specialist_output(const struct city *pcity,
+                         Specialist_type_id sp, Output_type_id otype);
+
 #define specialist_type_iterate(sp)                                        \
 {                                                                          \
   Specialist_type_id sp;                                                   \
Index: common/aicore/cm.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/aicore/cm.c,v
retrieving revision 1.65
diff -u -r1.65 cm.c
--- common/aicore/cm.c  10 May 2005 17:01:24 -0000      1.65
+++ common/aicore/cm.c  10 May 2005 18:48:19 -0000
@@ -925,7 +925,7 @@
     if (city_can_use_specialist(pcity, i)) {
       type.spec = i;
       output_type_iterate(output) {
-       type.production[output] = get_specialist(i)->bonus[output];
+       type.production[output] = get_specialist_output(pcity, i, output);
       } output_type_iterate_end;
 
       tile_type_lattice_add(lattice, &type, 0, 0);
Index: data/civ1/effects.ruleset
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/civ1/effects.ruleset,v
retrieving revision 1.6
diff -u -r1.6 effects.ruleset
--- data/civ1/effects.ruleset   7 May 2005 18:58:03 -0000       1.6
+++ data/civ1/effects.ruleset   10 May 2005 18:48:19 -0000
@@ -16,6 +16,37 @@
 ; /* <-- avoid gettext warnings
 ; */ <-- avoid gettext warnings
 
+
+; Specialist output bonuses
+
+[effect_elvis]
+name    = "Specialist_Output"
+value   = 2
+reqs    =
+    { "type", "name", "range"
+      "Specialist", "elvis", "Local"
+      "OutputType", "luxury", "Local"
+    }
+
+[effect_scientist]
+name    = "Specialist_Output"
+value   = 2
+reqs    =
+    { "type", "name", "range"
+      "Specialist", "scientist", "Local"
+      "OutputType", "science", "Local"
+    }
+
+[effect_taxman]
+name    = "Specialist_Output"
+value   = 2
+reqs    =
+    { "type", "name", "range"
+      "Specialist", "taxman", "Local"
+      "OutputType", "gold", "Local"
+    }
+
+
 [effect_civil_war_0]
 name    = "Civil_War_Chance"
 value   = 90
Index: data/civ2/effects.ruleset
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/civ2/effects.ruleset,v
retrieving revision 1.8
diff -u -r1.8 effects.ruleset
--- data/civ2/effects.ruleset   7 May 2005 18:58:03 -0000       1.8
+++ data/civ2/effects.ruleset   10 May 2005 18:48:19 -0000
@@ -16,6 +16,38 @@
 ; /* <-- avoid gettext warnings
 ; */ <-- avoid gettext warnings
 
+
+
+; Specialist output bonuses
+
+[effect_elvis]
+name    = "Specialist_Output"
+value   = 2
+reqs    =
+    { "type", "name", "range"
+      "Specialist", "elvis", "Local"
+      "OutputType", "luxury", "Local"
+    }
+
+[effect_scientist]
+name    = "Specialist_Output"
+value   = 2
+reqs    =
+    { "type", "name", "range"
+      "Specialist", "scientist", "Local"
+      "OutputType", "science", "Local"
+    }
+
+[effect_taxman]
+name    = "Specialist_Output"
+value   = 2
+reqs    =
+    { "type", "name", "range"
+      "Specialist", "taxman", "Local"
+      "OutputType", "gold", "Local"
+    }
+
+
 [effect_civil_war_0]
 name    = "Civil_War_Chance"
 value   = 90
Index: data/default/cities.ruleset
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/default/cities.ruleset,v
retrieving revision 1.17
diff -u -r1.17 cities.ruleset
--- data/default/cities.ruleset 2 May 2005 08:45:21 -0000       1.17
+++ data/default/cities.ruleset 10 May 2005 18:48:19 -0000
@@ -27,19 +27,17 @@
     { "type", "name", "range"
 ; Nothing
     }
-elvis_bonus_luxury = 2
 scientist_short_name = _("?Scientist:S")
 scientist_req  =
     { "type", "name", "range"
       "MinSize", "5", "City"
     }
-scientist_bonus_science = 3
+
 taxman_short_name = _("?Taxman:T")
 taxman_req     =
     { "type", "name", "range"
       "MinSize", "5", "City"
     }
-taxman_bonus_gold = 3
 
 changable_tax = 1
 ;forced_science = 0
Index: data/default/effects.ruleset
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/default/effects.ruleset,v
retrieving revision 1.9
diff -u -r1.9 effects.ruleset
--- data/default/effects.ruleset        7 May 2005 18:58:03 -0000       1.9
+++ data/default/effects.ruleset        10 May 2005 18:48:19 -0000
@@ -16,6 +16,37 @@
 ; /* <-- avoid gettext warnings
 ; */ <-- avoid gettext warnings
 
+
+; Specialist output bonuses
+
+[effect_elvis]
+name    = "Specialist_Output"
+value   = 2
+reqs    =
+    { "type", "name", "range"
+      "Specialist", "elvis", "Local"
+      "OutputType", "luxury", "Local"
+    }
+
+[effect_scientist]
+name    = "Specialist_Output"
+value   = 3
+reqs    =
+    { "type", "name", "range"
+      "Specialist", "scientist", "Local"
+      "OutputType", "science", "Local"
+    }
+
+[effect_taxman]
+name    = "Specialist_Output"
+value   = 3
+reqs    =
+    { "type", "name", "range"
+      "Specialist", "taxman", "Local"
+      "OutputType", "gold", "Local"
+    }
+
+
 ; Nuclear power gives +1 moves to sea units
 [effect_nuclear_powered_boats]
 name   = "Sea_Move"
Index: data/history/effects.ruleset
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/history/effects.ruleset,v
retrieving revision 1.6
diff -u -r1.6 effects.ruleset
--- data/history/effects.ruleset        7 May 2005 18:58:03 -0000       1.6
+++ data/history/effects.ruleset        10 May 2005 18:48:20 -0000
@@ -16,6 +16,37 @@
 ; /* <-- avoid gettext warnings
 ; */ <-- avoid gettext warnings
 
+
+; Specialist output bonuses
+
+[effect_elvis]
+name    = "Specialist_Output"
+value   = 2
+reqs    =
+    { "type", "name", "range"
+      "Specialist", "elvis", "Local"
+      "OutputType", "luxury", "Local"
+    }
+
+[effect_scientist]
+name    = "Specialist_Output"
+value   = 3
+reqs    =
+    { "type", "name", "range"
+      "Specialist", "scientist", "Local"
+      "OutputType", "science", "Local"
+    }
+
+[effect_taxman]
+name    = "Specialist_Output"
+value   = 3
+reqs    =
+    { "type", "name", "range"
+      "Specialist", "taxman", "Local"
+      "OutputType", "gold", "Local"
+    }
+
+
 ; Nuclear power gives +1 moves to sea units
 [effect_nuclear_powered_boats]
 name   = "Sea_Move"
Index: doc/README.effects
===================================================================
RCS file: /home/freeciv/CVS/freeciv/doc/README.effects,v
retrieving revision 1.12
diff -u -r1.12 README.effects
--- doc/README.effects  7 May 2005 18:58:04 -0000       1.12
+++ doc/README.effects  10 May 2005 18:48:20 -0000
@@ -115,6 +115,11 @@
 "Trade_Per_Tile" - increases trade generated on each worked tile
                  by AMOUNT percent
 
+"Specialist_Output" - increases specialist output (food, luxuries, etc.) by
+                  AMOUNT.  This is generally only useful in conjunction with
+                  a Specialist and an OutputType requirement, each at
+                  local range.  See the default ruleset for examples.
+
 "Food_Bonus"   - city's production is increased by AMOUNT percent
 "Prod_Bonus"
 "Trade_Bonus"
Index: server/citytools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/citytools.c,v
retrieving revision 1.325
diff -u -r1.325 citytools.c
--- server/citytools.c  10 May 2005 13:24:02 -0000      1.325
+++ server/citytools.c  10 May 2005 18:48:20 -0000
@@ -2074,7 +2074,7 @@
 
          if (req->source.type == REQ_TERRAIN
              && !is_req_active(city_owner(pcity), pcity, NULL,
-                               NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL,
                                req)) {
           do_sell_building(pplayer, pcity, impr);
           notify_player_ex(pplayer, tile1, E_IMP_SOLD,
Index: server/cityturn.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/cityturn.c,v
retrieving revision 1.314
diff -u -r1.314 cityturn.c
--- server/cityturn.c   10 May 2005 13:24:03 -0000      1.314
+++ server/cityturn.c   10 May 2005 18:48:21 -0000
@@ -697,7 +697,8 @@
          if (req->source.type == REQ_NONE) {
            break;
          }
-         if (!is_req_active(pplayer, pcity, NULL, NULL, NULL, NULL, req)) {
+         if (!is_req_active(pplayer, pcity, NULL, NULL, NULL, NULL, NULL,
+                            req)) {
            known = TRUE;
            switch (req->source.type) {
            case REQ_TECH:
@@ -754,10 +755,9 @@
              break;
            case REQ_UNITTYPE:
            case REQ_UNITFLAG:
-             /* Will only happen with a bogus ruleset. */
-             break;
            case REQ_OUTPUTTYPE:
-             /* Should never happen. */
+           case REQ_SPECIALIST:
+             /* Will only happen with a bogus ruleset. */
              break;
            case REQ_MINSIZE:
              notify_player_ex(pplayer, pcity->tile, E_CITY_CANTBUILD,
Index: server/ruleset.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/ruleset.c,v
retrieving revision 1.258
diff -u -r1.258 ruleset.c
--- server/ruleset.c    10 May 2005 17:01:24 -0000      1.258
+++ server/ruleset.c    10 May 2005 18:48:21 -0000
@@ -2266,7 +2266,6 @@
   for (i = 0; i < nval; i++) {
     const char *name = specialist_names[i], *short_name;
     struct specialist *s = &specialists[i];
-    int *bonus = s->bonus;
     int j;
 
     sz_strlcpy(s->name, name);
@@ -2275,12 +2274,6 @@
                                   "specialist.%s_short_name", name);
     sz_strlcpy(s->short_name, short_name);
 
-    output_type_iterate(o) {
-      bonus[o] = secfile_lookup_int_default(file, 0,
-                                           "specialist.%s_bonus_%s",
-                                           name, get_output_identifier(o));
-    } output_type_iterate_end;
-
     for (j = 0; j < MAX_NUM_REQS; j++) {
       const char *type
        = secfile_lookup_str_default(file, NULL, "specialist.%s_req%d.type",
@@ -2958,16 +2951,11 @@
   misc_p.default_specialist = DEFAULT_SPECIALIST;
   specialist_type_iterate(sp) {
     struct specialist *s = get_specialist(sp);
-    int *bonus = s->bonus;
     int j;
 
     sz_strlcpy(misc_p.specialist_name[sp], s->name);
     sz_strlcpy(misc_p.specialist_short_name[sp], s->short_name);
 
-    output_type_iterate(o) {
-      misc_p.specialist_bonus[sp * O_COUNT + o] = bonus[o];
-    } output_type_iterate_end;
-
     for (j = 0; j < MAX_NUM_REQS; j++) {
       int index = sp * MAX_NUM_REQS + j;
 

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#8759) effects to give bonuses to specialists, Jason Short <=