home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume13 / dominion / part20 / movement.c < prev    next >
C/C++ Source or Header  |  1992-02-11  |  7KB  |  259 lines

  1.   /* movement.c - routines that affect movement and move costs */
  2.  
  3. /*
  4.  * Copyright (C) 1990 Free Software Foundation, Inc.
  5.  * Written by the dominion project.
  6.  *
  7.  * This file is part of dominion.
  8.  *
  9.  * dominion is free software; you can redistribute it and/or
  10.  * modify it under the terms of the GNU General Public License as published
  11.  * by the Free Software Foundation; either version 1, or (at your option)
  12.  * any later version.
  13.  *
  14.  * This software is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this software; see the file COPYING.  If not, write to
  21.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  */
  23.  
  24. /* get_move_cost(np,sp) - calculates a sector's move cost for a nation    */
  25. /* get_army_move_cost(np,ap,sp) - calculates a sector's move cost
  26.    for a given army                                                       */
  27. /* good_altitude(sp,np) - TRUE if nation is compatible with sect. alt.    */
  28. /* good_army_altitude(np,sp,ap) - TRUE if army is compatible with sect. alt. */
  29.  
  30. #include "dominion.h"
  31. #include "misc.h"
  32. #include "army.h"
  33. #include <stdio.h>
  34.  
  35. #define TOO_MUCH_MOVE_COST 1000    /* basically impenetrable */
  36.  
  37.   /* returns the move cost for a given army over a given sector
  38.      if ap is NULL we should consider giving a "generic" move
  39.      cost for that sector.
  40.    */
  41. get_army_move_cost(np, sp, ap)
  42.      Snation *np;
  43.      Ssector *sp;
  44.      Sarmy *ap;
  45. {
  46.   int cost = 1;
  47.  
  48.   if (has_impenetrable(sp)) {
  49.     return TOO_MUCH_MOVE_COST;
  50.   }
  51.   cost += alt_mc(np, sp, ap);
  52.   cost += climate_mc(np, sp, ap);
  53.   cost += terrain_mc(np, sp, ap);
  54.   cost += patrol_mc(np, sp, ap);
  55.   cost += roads_mc(np, sp, ap);
  56.   cost += diplo_mc(np, sp, ap);
  57.   return max(1, cost);        /* can't be negative */
  58. }
  59.  
  60.   /* generic move cost for a given nation on a given
  61.      sector.  this is displayed in the sector window,
  62.      but can be quite different from the move
  63.      cost for an army with special flags. this value
  64.      is the move cost for a basic army type, such
  65.      as "Infantry".
  66.    */
  67. get_generic_move_cost(np, sp)
  68.      Snation *np;
  69.      Ssector *sp;
  70. {
  71.   int cost = 1;
  72.  
  73.   if (has_impenetrable(sp)) {
  74.     return 100;
  75.   }
  76.   cost += alt_mc(np, sp, NULL);
  77.   cost += climate_mc(np, sp, NULL);
  78.   cost += terrain_mc(np, sp, NULL);
  79.   cost += patrol_mc(np, sp, NULL);
  80.   cost += roads_mc(np, sp, NULL);
  81.   cost += diplo_mc(np, sp, NULL);
  82.   return max(1, cost);        /* can't be negative */
  83. }
  84.  
  85.   /* here follow a bunch of routines that give the
  86.      partial move cost for a given army on a given
  87.      sector, due to altitude, climate, diplomacy,
  88.      patrols, and so on...  if the army pointer
  89.      is NULL, then a "generic" value is returned
  90.      which does not account for special army flags
  91.    */
  92.   /* this macro does the real work */
  93. #define alt_cost(pref_alt, sp) (abs(pref_alt - sp->altitude)/2)
  94.  
  95. alt_mc(np, sp, ap)
  96.      Snation *np;
  97.      Ssector *sp;
  98.      Sarmy *ap;
  99. {
  100.   int virt_pref_alt = np->race.pref_alt; /* virtual preferred altitude */
  101.  
  102.   if (ap == NULL) {        /* generic value */
  103.     return alt_cost(virt_pref_alt, sp);
  104.   }
  105.     /* if ap is not null, we examine special army properties */
  106.   if (is_flight(ap)) {        /* flying armies ignore altitude */
  107.     return 0;
  108.   }
  109.  
  110.     /* see if army can make it into that sector */
  111.   if (!good_army_altitude(np, sp, ap)) {
  112.     return TOO_MUCH_MOVE_COST;
  113.   }
  114.   if (np->race.pref_alt >= SEA_LEVEL && sp->altitude < SEA_LEVEL
  115.       && is_water(ap)) {    /* water armies are adapted to shallows */
  116.     virt_pref_alt = SHALLOWS;
  117.   }
  118.   if (np->race.pref_alt < SEA_LEVEL && sp->altitude >= SEA_LEVEL
  119.       && is_land(ap)) {        /* land armies are adapted to lowlands */
  120.     virt_pref_alt = LOWLANDS;
  121.   }
  122.  
  123.   return alt_cost(virt_pref_alt, sp);
  124. }
  125.  
  126. climate_mc(np, sp, ap)
  127.      Snation *np;
  128.      Ssector *sp;
  129.      Sarmy *ap;
  130. {
  131.   int cost = 0;
  132.  
  133.   cost += abs(np->race.pref_climate - sp->climate)/3;
  134.   return cost;
  135. }
  136.  
  137. terrain_mc(np, sp, ap)
  138.      Snation *np;
  139.      Ssector *sp;
  140.      Sarmy *ap;
  141. {
  142.   int cost = 0;
  143.  
  144.   cost += abs(np->race.pref_terrain - sp->terrain)/2;
  145.   return cost;
  146. }
  147.  
  148. patrol_mc(np, sp, ap)
  149.      Snation *np;
  150.      Ssector *sp;
  151.      Sarmy *ap;
  152. {
  153.   int cost = 0;
  154.  
  155.   if (are_patrols(np, ap, sp)) {
  156.     cost += 5;
  157.   }
  158.   return cost;
  159. }
  160.  
  161. roads_mc(np, sp, ap)
  162.      Snation *np;
  163.      Ssector *sp;
  164.      Sarmy *ap;
  165. {
  166.   int cost = 0;
  167.  
  168.   cost -= sp->roads;
  169.   return cost;
  170. }
  171.  
  172. diplo_mc(np, sp, ap)
  173.      Snation *np;
  174.      Ssector *sp;
  175.      Sarmy *ap;
  176. {
  177.   int cost = 0;
  178.  
  179.   if (ap && is_flight(ap)) {    /* flying armies ignore diplomacy */
  180.     return cost;
  181.   }
  182.     /* here the move cost goes up if we are not buddy-buddy with the owner */
  183.   if (sp->owner != np->id) {
  184.     if (sp->owner == 0) {
  185.       cost += 2;
  186.     } else if (are_allied(np->id, sp->owner)) {
  187.       cost += 1;
  188.     } else {
  189.       cost += 5;        /* non-allied land: mucho move cost */
  190.     }
  191.   }
  192.   return cost;
  193. }
  194.  
  195.  
  196.   /* this takes care of whether a given race can
  197.      move to a given sector from the altitude point of view
  198.    */
  199. good_altitude(sp, np)
  200.      Ssector *sp;
  201.      Snation *np;
  202. {
  203.   if (sp->altitude >= SEA_LEVEL) { /* if above water */
  204.     return (np->race.pref_alt >= SEA_LEVEL || has_bubble(sp));
  205.   }
  206.   return (np->race.pref_alt < SEA_LEVEL || has_bubble(sp)); /* underwater */
  207. }
  208.   /* this takes care of whether a given army of a given race can
  209.      move to a given sector from the altitude point of view
  210.    */
  211. good_army_altitude(np, sp, ap)
  212.      Snation *np;
  213.      Ssector *sp;
  214.      Sarmy *ap;
  215. {
  216.   if (has_bubble(sp)) {
  217.     return 1;
  218.   }
  219.   if (is_water(ap) && is_land(ap)) {
  220.     return 1;
  221.   }
  222.   if (is_in_transport(ap)) {
  223.     return 1;            /* carried by someone else */
  224.   }
  225.     /* first look at the case where we are above water */
  226.   if (sp->altitude >= SEA_LEVEL) {
  227.     if (np->race.pref_alt >= SEA_LEVEL) {
  228.         /* water armies can only be in water (for land race) */
  229.       if (is_water(ap) && !is_coastal_sect(np, sp, ap)) {
  230.     return 0;
  231.       }
  232.       return 1;            /* it's OK: land army on land. */
  233.     }
  234.       /* otherwise we are a water race on land */
  235.     if (is_land(ap)) {
  236.       return 1;
  237.     }
  238.     if (is_water(ap) && is_coastal_sect(np, sp, ap)) {
  239.       return 1;            /* water army can stay on coast */
  240.     }
  241.     return 0;
  242.   }
  243.     /* now the case where we are an underwater sector */
  244.   if (np->race.pref_alt >= SEA_LEVEL) { /* land race under water */
  245.     if (is_water(ap)) {
  246.       return 1;
  247.     }
  248.     return 0;
  249.   }
  250.     /* now the case of a water race under water */
  251.   if (is_land(ap) && !is_coastal_sect(np, sp, ap)) {
  252.     return 0;
  253.   }
  254.   return 1;
  255.  
  256.  
  257. /*  return (np->race.pref_alt < SEA_LEVEL || has_bubble(sp)); /* underwater */
  258. }
  259.