travel.c

Go to the documentation of this file.
00001 /*      module TRAVEL.C                                         *
00002  *      Routine to handle motion requests                       */
00003 
00004 
00005 #include        <stdio.h>
00006 #include        <stdlib.h>
00007 #include        "advent.h"
00008 #include        "advdec.h"
00009 #include        "advcave.h"
00010 
00011 struct trav travel[MAXTRAV];
00012 static int kalflg;
00013 static int bcrossing = 0;
00014 static int phuce[2][4] = {158, 160, 167, 166,
00015                           160, 158, 166, 167};
00016 
00017 _PROTOTYPE(static void goback, (void));
00018 _PROTOTYPE(static void ck_kal, (void));
00019 _PROTOTYPE(static void dotrav, (void));
00020 _PROTOTYPE(static void badmove, (void));
00021 _PROTOTYPE(static void spcmove, (int rdest));
00022 
00023 void domove()
00024 {
00025     gettrav(g.loc, travel);
00026     switch (motion) {
00027     case NULLX:
00028         break;
00029     case BACK:
00030         goback();
00031         break;
00032     case CAVE:
00033         if (outside(g.loc))
00034             rspeak(57);
00035         else
00036             rspeak(58);
00037         break;
00038     default:
00039         g.oldloc2 = g.oldloc;
00040         g.oldloc = g.loc;
00041         dotrav();
00042     }
00043     newtravel = TRUE;
00044     return;
00045 }
00046 
00047 /*
00048   Routine to handle request to return
00049   from whence we came!
00050 */
00051 static void goback()
00052 {
00053     int kk, k2, want, temp;
00054     struct trav strav[MAXTRAV];
00055 
00056     want = forced(g.oldloc) ? g.oldloc2 : g.oldloc;
00057     g.oldloc2 = g.oldloc;
00058     g.oldloc = g.loc;
00059     k2 = 0;
00060     if (want == g.loc) {
00061         rspeak(91);
00062         ck_kal();
00063         return;
00064     }
00065     for (kk = 0; travel[kk].tdest != -1; ++kk) {
00066         if (!travel[kk].tcond && travel[kk].tdest == want) {
00067             motion = travel[kk].tverb;
00068             dotrav();
00069             return;
00070         }
00071         if (!travel[kk].tcond) {
00072             temp = travel[kk].tdest;
00073             gettrav(temp, strav);
00074             if (forced(temp) && strav[0].tdest == want)
00075                 k2 = temp;
00076         }
00077     }
00078     if (k2) {
00079         motion = travel[k2].tverb;
00080         dotrav();
00081     } else
00082         rspeak(140);
00083     ck_kal();
00084     return;
00085 }
00086 
00087 static void ck_kal()
00088 {
00089     if (g.newloc >= 242 && g.newloc <= 247) {
00090         if (g.newloc == 242)
00091             kalflg = 0;
00092         else if (g.newloc == (g.oldloc + 1))
00093             kalflg++;
00094         else
00095             kalflg = -10;
00096     }
00097 }
00098 
00099 /*
00100   Routine to figure out a new location
00101   given current location and a motion.
00102 */
00103 static void dotrav()
00104 {
00105     unsigned char mvflag, hitflag, kk;
00106     int rdest, rverb, rcond, robject;
00107     int pctt;
00108 
00109     g.newloc = g.loc;
00110     mvflag = hitflag = 0;
00111     pctt = ranz(100);
00112 
00113     for (kk = 0; travel[kk].tdest >= 0 && !mvflag; ++kk) {
00114         rdest = travel[kk].tdest;
00115         rverb = travel[kk].tverb;
00116         rcond = travel[kk].tcond;
00117         robject = rcond % 100;
00118 
00119         if ((rverb != 1) && (rverb != motion) && !hitflag)
00120             continue;
00121         ++hitflag;
00122         switch (rcond / 100) {
00123         case 0:
00124             if ((rcond == 0) || (pctt < rcond))
00125                 ++mvflag;
00126             break;
00127         case 1:
00128             if (robject == 0)
00129                 ++mvflag;
00130             else if (toting(robject))
00131                 ++mvflag;
00132             break;
00133         case 2:
00134             if (toting(robject) || at(robject))
00135                 ++mvflag;
00136             break;
00137         case 3:
00138         case 4:
00139         case 5:
00140         case 7:
00141             if (g.prop[robject] != (rcond / 100) - 3)
00142                 ++mvflag;
00143             break;
00144         default:
00145             bug(37);
00146         }
00147     }
00148     if (!mvflag)
00149         badmove();
00150     else if (rdest > 500)
00151         rspeak(rdest - 500);
00152     else if (rdest > 300)
00153         spcmove(rdest);
00154     else {
00155         g.newloc = rdest;
00156         ck_kal();
00157     }
00158     newtravel = TRUE;
00159     return;
00160 }
00161 
00162 /*
00163   The player tried a poor move option.
00164 */
00165 static void badmove()
00166 {
00167     int msg;
00168 
00169     msg = 12;
00170     if (motion >= 43 && motion <= 50)
00171         msg = 9;
00172     if (motion == 29 || motion == 30)
00173         msg = 9;
00174     if (motion == 7 || motion == 36 || motion == 37)
00175         msg = 10;
00176     if (motion == 11 || motion == 19)
00177         msg = 11;
00178     if (motion == 62 || motion == 65 || motion == 82)
00179         msg = 42;
00180     if (motion == 17)
00181         msg = 80;
00182     rspeak(msg);
00183     return;
00184 }
00185 
00186 /*
00187   Routine to handle very special movement.
00188 */
00189 static void spcmove(rdest)
00190 int rdest;
00191 {
00192     int load, obj, k;
00193 
00194     switch (rdest - 300) {
00195     case 1:                             /* plover movement via alcove */
00196         load = burden(0);
00197         if (!load || (load == burden(EMERALD) && holding(EMERALD)))
00198             g.newloc = (99 + 100) - g.loc;
00199         else
00200             rspeak(117);
00201         break;
00202     case 2:                             /* trying to remove plover, bad
00203                                            route */
00204         if (enclosed(EMERALD))
00205             extract(EMERALD);
00206         drop(EMERALD, g.loc);
00207         g.newloc = 33;
00208         break;
00209     case 3:                             /* troll bridge */
00210         if (g.prop[TROLL] == 1) {
00211             pspeak(TROLL, 1);
00212             g.prop[TROLL] = 0;
00213             move(TROLL2, 0);
00214             move((TROLL2 + MAXOBJ), 0);
00215             move(TROLL, plac[TROLL]);
00216             move((TROLL + MAXOBJ), fixd[TROLL]);
00217             juggle(CHASM);
00218             g.newloc = g.loc;
00219         } else {
00220             g.newloc = plac[TROLL] + fixd[TROLL] - g.loc;
00221             if (g.prop[TROLL] == 0)
00222                 g.prop[TROLL] = 1;
00223             if (toting(BEAR)) {
00224                 rspeak(162);
00225                 g.prop[CHASM] = 1;
00226                 g.prop[TROLL] = 2;
00227                 drop(BEAR, g.newloc);
00228                 g.fixed[BEAR] = -1;
00229                 g.prop[BEAR] = 3;
00230                 if (g.prop[SPICES] < 0)
00231                     ++g.tally2;
00232                 g.oldloc2 = g.newloc;
00233                 death();
00234             }
00235         }
00236         break;
00237     case 4:
00238         /* Growing or shrinking in area of tiny door.  Each time he
00239            does this, everything must be moved to the new loc.
00240            Presumably, all his possesions are shrunk or streched along
00241            with him. Phuce[2][4] is an array containg four pairs of
00242            "here" (K) and "there" (KK) locations. */
00243         k = phuce[0][g.loc - 161];
00244         g.newloc = phuce[1][g.loc - 161];
00245         for (obj = 1; obj < MAXOBJ; obj++) {
00246             if (obj == BOAT)
00247                 continue;
00248             if (g.place[obj] == k && (g.fixed[obj] == 0 || g.fixed[obj] == -1))
00249                 move(obj, g.newloc);
00250         }
00251         break;
00252     case 5:
00253         /* Phone booth in rotunda. Trying to shove past gnome, to get
00254            into phone booth. */
00255         if ((g.prop[BOOTH] == 0 && pct(35)) || g.visited[g.loc] == 1) {
00256             rspeak(263);
00257             g.prop[BOOTH] = 1;
00258             move(GNOME, 188);
00259         } else {
00260             if (g.prop[BOOTH] == 1)
00261                 rspeak(253);
00262             else
00263                 g.newloc = 189;
00264         }
00265         break;
00266     case 6:
00267         /* Collapsing clay bridge.  He can cross with three (or fewer)
00268            thing.  If more, of if carrying obviously heavy things, he
00269            may end up in the drink. */
00270         g.newloc = g.loc == 235 ? 190 : 235;
00271         bcrossing++;
00272         load = burden(0);
00273         if (load > 4) {
00274             k = (load + bcrossing) * 6 - 10;
00275             if (!pct(k))
00276                 rspeak(318);
00277             else {
00278                 rspeak(319);
00279                 g.newloc = 236;
00280                 if (holding(LAMP))
00281                     move(LAMP, 236);
00282                 if (toting(AXE) && enclosed(AXE))
00283                     extract(AXE);
00284                 if (holding(AXE))
00285                     move(AXE, 208);
00286                 for (obj = 1; obj < MAXOBJ; obj++)
00287                     if (toting(obj))
00288                         destroy(obj);
00289                 g.prop[CHASM2] = 1;
00290             }
00291         }
00292         break;
00293     case 7:
00294         /* Kaleidoscope code is here. */
00295         if (kalflg == 5) {
00296             g.newloc = 248;
00297             g.oldloc = 247;
00298         } else {
00299             g.newloc = 242 + ranz(5);
00300             g.oldloc = g.newloc - 1;
00301             kalflg = g.newloc == 242 ? 0 : -10;
00302         }
00303         break;
00304     default:
00305         bug(38);
00306     }
00307     return;
00308 }
00309 
00310 /*
00311   Routine to fill travel array for a given location
00312 */
00313 void gettrav(loc, travel)
00314 int loc;
00315 struct trav *travel;
00316 {
00317     int i;
00318     long t, *lptr;
00319 
00320     lptr = cave[loc - 1];
00321     for (i = 0; i < MAXTRAV; i++) {
00322         t = *lptr++;
00323         if (!(t)) {
00324             travel->tdest = -1;         /* end of array  */
00325             return;                     /* terminate for loop    */
00326         }
00327         travel->tverb = (int) (t % 1000);
00328         t /= 1000;
00329         travel->tdest = (int) (t % 1000);
00330         t /= 1000;
00331         travel->tcond = (int) (t % 1000);
00332         travel++;
00333     }
00334     bug(25);
00335     return;
00336 }

Generated on Fri Apr 14 22:56:39 2006 for minix by  doxygen 1.4.6