Complete.Org: Mailing Lists: Archives: freeciv-dev: May 2005:
[Freeciv-Dev] (PR#12994) requirements of unittypes
Home

[Freeciv-Dev] (PR#12994) requirements of unittypes

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#12994) requirements of unittypes
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 5 May 2005 14:34:21 -0700
Reply-to: bugs@xxxxxxxxxxx

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

This patch adds a UnitType req.  Currently this can be applied only at
local range.  It should be used by effect types that modify units
abilities.  Currently there is only one such effect type, EFT_SEA_MOVE.

Also attached is a patch that shows the req in action.

-jason

Index: ai/aicity.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/ai/aicity.c,v
retrieving revision 1.219
diff -u -r1.219 aicity.c
--- ai/aicity.c 5 May 2005 20:00:41 -0000       1.219
+++ ai/aicity.c 5 May 2005 21:32:40 -0000
@@ -278,7 +278,7 @@
     struct requirement *mypreq;
     bool useful;
 
-    if (is_effect_disabled(pplayer, pcity, pimpr, NULL, peffect)) {
+    if (is_effect_disabled(pplayer, pcity, pimpr, NULL, NULL, peffect)) {
       CITY_LOG(LOG_DEBUG, pcity, "%s has a disabled effect: %s", 
                get_improvement_name(id), effect_type_name(peffect->type));
       continue;
@@ -294,7 +294,7 @@
        mypreq = preq;
         continue;
       }
-      if (!is_req_active(pplayer, pcity, pimpr, NULL, preq)) {
+      if (!is_req_active(pplayer, pcity, pimpr, NULL, NULL, preq)) {
        useful = FALSE;
        break;
       }
Index: client/helpdata.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/helpdata.c,v
retrieving revision 1.110
diff -u -r1.110 helpdata.c
--- client/helpdata.c   5 May 2005 20:00:42 -0000       1.110
+++ client/helpdata.c   5 May 2005 21:32:41 -0000
@@ -186,6 +186,10 @@
     cat_snprintf(buf, bufsz, _("Requires the %s nation.\n\n"),
                 get_nation_name(req->source.value.nation));
     return;
+  case REQ_UNITTYPE:
+    cat_snprintf(buf, bufsz, _("Only applies to %s units.\n\n"),
+                unit_name(req->source.value.unittype));
+    return;
   case REQ_MINSIZE:
     cat_snprintf(buf, bufsz, _("Requires a minimum size of %d.\n\n"),
                 req->source.value.minsize);
Index: common/capstr.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/capstr.c,v
retrieving revision 1.242
diff -u -r1.242 capstr.c
--- common/capstr.c     5 May 2005 20:26:13 -0000       1.242
+++ common/capstr.c     5 May 2005 21:32:41 -0000
@@ -82,7 +82,7 @@
  *     as long as possible.  We want to maintain network compatibility with
  *     the stable branch for as long as possible.
  */
-#define CAPABILITY "+Freeciv.Devel.2005.May.5-3"
+#define CAPABILITY "+Freeciv.Devel.2005.May.5-4"
 
 void init_our_capability(void)
 {
Index: common/city.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/city.c,v
retrieving revision 1.340
diff -u -r1.340 city.c
--- common/city.c       5 May 2005 18:32:49 -0000       1.340
+++ common/city.c       5 May 2005 21:32:41 -0000
@@ -525,7 +525,7 @@
     if (building->req[i].source.type == REQ_NONE) {
       break;
     }
-    if (!is_req_active(city_owner(pcity), pcity, 0, pcity->tile,
+    if (!is_req_active(city_owner(pcity), pcity, NULL, pcity->tile, NULL,
                       &building->req[i])) {
       return FALSE;
     }
@@ -572,7 +572,7 @@
       break;
     }
     if (is_req_unchanging(&building->req[r])
-       && !is_req_active(city_owner(pcity), pcity, NULL, pcity->tile,
+       && !is_req_active(city_owner(pcity), pcity, NULL, pcity->tile, NULL,
                          &building->req[r])) {
       return FALSE;
     }
@@ -650,7 +650,7 @@
 bool city_can_use_specialist(const struct city *pcity,
                             Specialist_type_id type)
 {
-  return are_reqs_active(city_owner(pcity), pcity, NULL, NULL,
+  return are_reqs_active(city_owner(pcity), pcity, NULL, NULL, NULL,
                         game.rgame.specialists[type].req, MAX_NUM_REQS);
 }
 
@@ -1238,7 +1238,7 @@
 
   while ((replace = city_styles[prev].replaced_by) != -1) {
     prev = replace;
-    if (are_reqs_active(plr, NULL, NULL, NULL,
+    if (are_reqs_active(plr, NULL, NULL, NULL, NULL,
                        city_styles[replace].req, MAX_NUM_REQS)) {
       style = replace;
     }
Index: common/effects.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/effects.c,v
retrieving revision 1.37
diff -u -r1.37 effects.c
--- common/effects.c    5 May 2005 20:00:42 -0000       1.37
+++ common/effects.c    5 May 2005 21:32:41 -0000
@@ -577,11 +577,12 @@
                        const struct city *target_city,
                        const struct impr_type *target_building,
                        const struct tile *target_tile,
+                       const struct unit *target_unit,
                        const struct effect *peffect)
 {
   requirement_list_iterate(peffect->nreqs, preq) {
     if (is_req_active(target_player, target_city, target_building,
-                     target_tile, preq)) {
+                     target_tile, target_unit, preq)) {
       return TRUE;
     }
   } requirement_list_iterate_end;
@@ -597,11 +598,12 @@
                              const struct city *target_city,
                              const struct impr_type *target_building,
                              const struct tile *target_tile,
+                             const struct unit *target_unit,
                              const struct effect *peffect)
 {
   requirement_list_iterate(peffect->reqs, preq) {
     if (!is_req_active(target_player, target_city, target_building,
-                      target_tile, preq)) {
+                      target_tile, target_unit, preq)) {
       return FALSE;
     }
   } requirement_list_iterate_end;
@@ -621,12 +623,13 @@
                             const struct city *target_city,
                             const struct impr_type *target_building,
                             const struct tile *target_tile,
+                            const struct unit *target_unit,
                             const struct effect *peffect)
 {
   return is_effect_enabled(target_player, target_city, target_building,
-                          target_tile, peffect)
+                          target_tile, target_unit, peffect)
     && !is_effect_disabled(target_player, target_city, target_building,
-                          target_tile, peffect);
+                          target_tile, target_unit, peffect);
 }
 
 /**************************************************************************
@@ -645,10 +648,12 @@
                      const struct city *target_city,
                      const struct impr_type *target_building,
                      const struct tile *target_tile,
+                     const struct unit *target_unit,
                      Impr_type_id source, const struct effect *peffect)
 {
   if (is_effect_disabled(target_player, target_city,
-                        target_building, target_tile, peffect)) {
+                        target_building, target_tile, target_unit,
+                        peffect)) {
     return FALSE;
   }
   requirement_list_iterate(peffect->reqs, preq) {
@@ -657,7 +662,7 @@
       continue;
     }
     if (!is_req_active(target_player, target_city, target_building,
-                      target_tile, preq)) {
+                      target_tile, target_unit, preq)) {
       return FALSE;
     }
   } requirement_list_iterate_end;
@@ -688,7 +693,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, peffect)) {
+                           get_improvement_type(building), NULL, NULL,
+                           peffect)) {
       return FALSE;
     }
   } effect_list_iterate_end;
@@ -712,6 +718,7 @@
                                    const struct city *target_city,
                                    const struct impr_type *target_building,
                                    const struct tile *target_tile,
+                                   const struct unit *target_unit,
                                    enum effect_type effect_type)
 {
   int bonus = 0;
@@ -720,7 +727,8 @@
   effect_list_iterate(get_effects(effect_type), peffect) {
     /* For each effect, see if it is active. */
     if (is_effect_active(target_player, target_city,
-                        target_building, target_tile, peffect)) {
+                        target_building, target_tile, target_unit,
+                        peffect)) {
       /* And if so add on the value. */
       bonus += peffect->value;
 
@@ -742,8 +750,8 @@
     return 0;
   }
 
-  return get_target_bonus_effects(NULL,
-                                 NULL, NULL, NULL, NULL, effect_type);
+  return get_target_bonus_effects(NULL, NULL, NULL, NULL, NULL, NULL,
+                                 effect_type);
 }
 
 /**************************************************************************
@@ -756,8 +764,7 @@
     return 0;
   }
 
-  return get_target_bonus_effects(NULL,
-                                 pplayer, NULL, NULL, NULL,
+  return get_target_bonus_effects(NULL, pplayer, NULL, NULL, NULL, NULL,
                                  effect_type);
 }
 
@@ -770,8 +777,8 @@
     return 0;
   }
 
-  return get_target_bonus_effects(NULL,
-                                 city_owner(pcity), pcity, NULL, NULL,
+  return get_target_bonus_effects(NULL, city_owner(pcity), pcity,
+                                 NULL, NULL, NULL,
                                  effect_type);
 }
 
@@ -784,6 +791,7 @@
   assert(pcity != NULL && ptile != NULL);
   return get_target_bonus_effects(NULL,
                                  city_owner(pcity), pcity, NULL, ptile,
+                                 NULL,
                                  effect_type);
 }
 
@@ -796,7 +804,18 @@
   assert(pcity != NULL && id != B_LAST);
   return get_target_bonus_effects(NULL,
                                  city_owner(pcity), pcity,
-                                 get_improvement_type(id), NULL,
+                                 get_improvement_type(id), NULL, NULL,
+                                 effect_type);
+}
+
+/**************************************************************************
+  Returns the effect bonus at a building.
+**************************************************************************/
+int get_unit_bonus(const struct unit *punit, enum effect_type effect_type)
+{
+  assert(punit != NULL);
+  return get_target_bonus_effects(NULL, unit_owner(punit), NULL,
+                                 NULL, NULL, punit,
                                  effect_type);
 }
 
@@ -812,7 +831,7 @@
 {
   assert(pplayer != NULL);
   return get_target_bonus_effects(plist,
-                                 pplayer, NULL, NULL, NULL,
+                                 pplayer, NULL, NULL, NULL, NULL,
                                  effect_type);
 }
 
@@ -828,7 +847,7 @@
 {
   assert(pcity != NULL);
   return get_target_bonus_effects(plist,
-                                 city_owner(pcity), pcity, NULL, NULL,
+                                 city_owner(pcity), pcity, NULL, NULL, NULL,
                                  effect_type);
 }
 
@@ -859,7 +878,7 @@
          continue;
        }
        if (is_effect_useful(city_owner(pcity),
-                            pcity, building, NULL, id, peffect)) {
+                            pcity, building, NULL, NULL, id, peffect)) {
          power += peffect->value;
        }
       } effect_list_iterate_end;
Index: common/effects.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/effects.h,v
retrieving revision 1.22
diff -u -r1.22 effects.h
--- common/effects.h    5 May 2005 20:00:42 -0000       1.22
+++ common/effects.h    5 May 2005 21:32:41 -0000
@@ -180,6 +180,7 @@
                      const struct city *target_pcity,
                      const struct impr_type *target_building,
                      const struct tile *target_tile,
+                     const struct unit *target_unit,
                      Impr_type_id source, const struct effect *effect);
 
 bool is_building_replaced(const struct city *pcity, Impr_type_id building);
@@ -192,6 +193,7 @@
                        enum effect_type effect_type);
 int get_building_bonus(const struct city *pcity, Impr_type_id building,
                       enum effect_type effect_type);
+int get_unit_bonus(const struct unit *punit, enum effect_type effect_type);
 
 /* miscellaneous auxiliary effects functions */
 struct effect_list *get_req_source_effects(struct req_source *psource);
@@ -199,6 +201,7 @@
                        const struct city *target_city,
                        const struct impr_type *target_building,
                        const struct tile *target_tile,
+                       const struct unit *target_unit,
                        const struct effect *peffect);
 
 int get_player_bonus_effects(struct effect_list *plist,
Index: common/government.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/government.c,v
retrieving revision 1.55
diff -u -r1.55 government.c
--- common/government.c 5 May 2005 18:32:49 -0000       1.55
+++ common/government.c 5 May 2005 21:32:41 -0000
@@ -148,7 +148,7 @@
     return TRUE;
   }
 
-  return are_reqs_active(pplayer, NULL, NULL, NULL,
+  return are_reqs_active(pplayer, 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.59
diff -u -r1.59 improvement.c
--- common/improvement.c        5 May 2005 18:32:49 -0000       1.59
+++ common/improvement.c        5 May 2005 21:32:41 -0000
@@ -305,7 +305,7 @@
       break;
     }
     if (impr->req[i].range >= REQ_RANGE_PLAYER
-       && !is_req_active(p, NULL, 0, NULL, &impr->req[i])) {
+       && !is_req_active(p, NULL, 0, NULL, NULL, &impr->req[i])) {
       return FALSE;
     }
   }
@@ -389,7 +389,7 @@
     }
     if (building->req[r].range >= REQ_RANGE_PLAYER
        && is_req_unchanging(&building->req[r])
-       && !is_req_active(p, NULL, NULL, NULL, &building->req[r])) {
+       && !is_req_active(p, NULL, NULL, NULL, NULL, &building->req[r])) {
       return FALSE;
     }
   }
Index: common/movement.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/movement.c,v
retrieving revision 1.6
diff -u -r1.6 movement.c
--- common/movement.c   3 May 2005 19:10:59 -0000       1.6
+++ common/movement.c   5 May 2005 21:32:42 -0000
@@ -61,7 +61,7 @@
 
     /* Add on effects bonus (Magellan's Expedition, Lighthouse,
      * Nuclear Power). */
-    move_rate += (get_player_bonus(unit_owner(punit), EFT_SEA_MOVE)
+    move_rate += (get_unit_bonus(punit, EFT_SEA_MOVE)
                  * SINGLE_MOVE);
 
     /* Don't let the move_rate be less than 2 unless the base_move_rate is
Index: common/requirements.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/requirements.c,v
retrieving revision 1.19
diff -u -r1.19 requirements.c
--- common/requirements.c       5 May 2005 18:32:52 -0000       1.19
+++ common/requirements.c       5 May 2005 21:32:42 -0000
@@ -36,6 +36,7 @@
   "Special",
   "Terrain",
   "Nation",
+  "UnitType",
   "MinSize"
 };
 
@@ -136,6 +137,12 @@
       return source;
     }
     break;
+  case REQ_UNITTYPE:
+    source.value.unittype = find_unit_type_by_name(value);
+    if (source.value.unittype != U_LAST) {
+      return source;
+    }
+    break;
   case REQ_MINSIZE:
     source.value.minsize = atoi(value);
     if (source.value.minsize > 0) {
@@ -182,6 +189,9 @@
   case REQ_NATION:
     source.value.nation = value;
     return source;
+  case REQ_UNITTYPE:
+    source.value.unittype = value;
+    return source;
   case REQ_MINSIZE:
     source.value.minsize = value;
     return source;
@@ -225,6 +235,9 @@
   case REQ_NATION:
     *value = source->value.nation;
     return;
+  case REQ_UNITTYPE:
+    *value = source->value.unittype;
+    return;
   case REQ_MINSIZE:
     *value = source->value.minsize;
     return;
@@ -263,6 +276,7 @@
     case REQ_BUILDING:
     case REQ_SPECIAL:
     case REQ_TERRAIN:
+    case REQ_UNITTYPE:
       req.range = REQ_RANGE_LOCAL;
       break;
     case REQ_MINSIZE:
@@ -305,6 +319,9 @@
     invalid = (req.range != REQ_RANGE_PLAYER
               && req.range != REQ_RANGE_WORLD);
     break;
+  case REQ_UNITTYPE:
+    invalid = (req.range != REQ_RANGE_LOCAL);
+    break;
   case REQ_NONE:
     invalid = FALSE;
     break;
@@ -630,6 +647,18 @@
 }
 
 /****************************************************************************
+  Is there a unit of the given type within range of the target?
+****************************************************************************/
+static bool is_unittype_in_range(const struct unit *target_unit,
+                                enum req_range range, bool survives,
+                                Unit_type_id unittype)
+{
+  return (range == REQ_RANGE_LOCAL
+         && target_unit
+         && target_unit->type == unittype);
+}
+
+/****************************************************************************
   Checks the requirement to see if it is active on the given target.
 
   target gives the type of the target
@@ -644,6 +673,7 @@
                   const struct city *target_city,
                   const struct impr_type *target_building,
                   const struct tile *target_tile,
+                  const struct unit *target_unit,
                   const struct requirement *req)
 {
   /* Note the target may actually not exist.  In particular, effects that
@@ -680,6 +710,10 @@
   case REQ_NATION:
     return is_nation_in_range(target_player, req->range, req->survives,
                              req->source.value.nation);
+  case REQ_UNITTYPE:
+    return is_unittype_in_range(target_unit,
+                               req->range, req->survives,
+                               req->source.value.unittype);
   case REQ_MINSIZE:
     return target_city && target_city->size >= req->source.value.minsize;
   case REQ_LAST:
@@ -708,6 +742,7 @@
                     const struct city *target_city,
                     const struct impr_type *target_building,
                     const struct tile *target_tile,
+                    const struct unit *target_unit,
                     const struct requirement *reqs, int num_reqs)
 {
   int i;
@@ -716,7 +751,7 @@
     if (reqs[i].source.type == REQ_NONE) {
       break; /* Short-circuit any more checks. */
     } else if (!is_req_active(target_player, target_city,
-                             target_building, target_tile,
+                             target_building, target_tile, target_unit,
                              &reqs[i])) {
       return FALSE;
     }
@@ -745,6 +780,7 @@
   case REQ_GOV:
   case REQ_BUILDING:
   case REQ_MINSIZE:
+  case REQ_UNITTYPE: /* Not sure about this one */
     return FALSE;
   case REQ_SPECIAL:
   case REQ_TERRAIN:
@@ -785,6 +821,8 @@
     return psource1->value.terrain == psource2->value.terrain;
   case REQ_NATION:
     return psource1->value.nation == psource2->value.nation;
+  case REQ_UNITTYPE:
+    return psource1->value.unittype == psource2->value.unittype;
   case REQ_MINSIZE:
     return psource1->value.minsize == psource2->value.minsize;
   case REQ_LAST:
@@ -824,6 +862,9 @@
   case REQ_NATION:
     mystrlcat(buf, get_nation_name(psource->value.nation), bufsz);
     break;
+  case REQ_UNITTYPE:
+    mystrlcat(buf, unit_name(psource->value.unittype), bufsz);
+    break;
   case REQ_MINSIZE:
     cat_snprintf(buf, bufsz, "Size %d", psource->value.minsize);
     break;
Index: common/requirements.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/requirements.h,v
retrieving revision 1.13
diff -u -r1.13 requirements.h
--- common/requirements.h       30 Apr 2005 17:09:27 -0000      1.13
+++ common/requirements.h       5 May 2005 21:32:42 -0000
@@ -27,6 +27,7 @@
   REQ_SPECIAL,
   REQ_TERRAIN,
   REQ_NATION,
+  REQ_UNITTYPE,
   REQ_MINSIZE, /* Minimum size: at city range means city size */
   REQ_LAST
 };
@@ -54,6 +55,7 @@
     enum tile_special_type special;     /* source special */
     Terrain_type_id terrain;            /* source terrain type */
     Nation_type_id nation;              /* source nation type */
+    Unit_type_id unittype;              /* source unittype */
     int minsize;                        /* source minsize type */
   } value;                              /* source value */
 };
@@ -100,11 +102,13 @@
                   const struct city *target_city,
                   const struct impr_type *target_building,
                   const struct tile *target_tile,
+                  const struct unit *target_unit,
                   const struct requirement *req);
 bool are_reqs_active(const struct player *target_player,
                     const struct city *target_city,
                     const struct impr_type *target_building,
                     const struct tile *target_tile,
+                    const struct unit *target_unit,
                     const struct requirement *reqs, int num_reqs);
 
 bool is_req_unchanging(const struct requirement *req);
Index: server/citytools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/citytools.c,v
retrieving revision 1.321
diff -u -r1.321 citytools.c
--- server/citytools.c  5 May 2005 18:32:52 -0000       1.321
+++ server/citytools.c  5 May 2005 21:32:42 -0000
@@ -2065,7 +2065,8 @@
          struct requirement *req = &get_improvement_type(impr)->req[r];
 
          if (req->source.type == REQ_TERRAIN
-             && !is_req_active(city_owner(pcity), pcity, NULL, NULL, req)) {
+             && !is_req_active(city_owner(pcity), pcity, NULL, NULL, NULL,
+                               req)) {
           do_sell_building(pplayer, pcity, impr);
           notify_player_ex(pplayer, tile1, E_IMP_SOLD,
                            _("You sell %s in %s (now landlocked)"
Index: server/cityturn.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/cityturn.c,v
retrieving revision 1.310
diff -u -r1.310 cityturn.c
--- server/cityturn.c   5 May 2005 18:32:52 -0000       1.310
+++ server/cityturn.c   5 May 2005 21:32:43 -0000
@@ -693,7 +693,7 @@
          if (req->source.type == REQ_NONE) {
            break;
          }
-         if (!is_req_active(pplayer, pcity, 0, NULL, req)) {
+         if (!is_req_active(pplayer, pcity, NULL, NULL, NULL, req)) {
            known = TRUE;
            switch (req->source.type) {
            case REQ_TECH:
@@ -748,6 +748,9 @@
                               get_impr_name_ex(pcity, target),
                               get_nation_name(req->source.value.nation));
              break;
+           case REQ_UNITTYPE:
+             /* Will only happen with a bogus ruleset. */
+             break;
            case REQ_MINSIZE:
              notify_player_ex(pplayer, pcity->tile, E_CITY_CANTBUILD,
                               _("%s can't build %s from the worklist; "
Index: data/default/effects.ruleset
===================================================================
RCS file: /home/freeciv/CVS/freeciv/data/default/effects.ruleset,v
retrieving revision 1.8
diff -u -r1.8 effects.ruleset
--- data/default/effects.ruleset        5 May 2005 21:14:57 -0000       1.8
+++ data/default/effects.ruleset        5 May 2005 21:29:56 -0000
@@ -1234,6 +1234,14 @@
       "Building", "Lighthouse", "Player"
     }
 
+[effect_superfrigates]
+name   = "Sea_Move"
+value  = 10
+reqs   =
+    { "type", "name", "range"
+      "Unittype", "Frigate", "local"
+    }
+
 [effect_lighthouse_1]
 name   = "No_Sink_Deep"
 value  = 1

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#12994) requirements of unittypes, Jason Short <=