mc.c

Go to the documentation of this file.
00001 /*
00002     Copyright (C) 2005 Michael K. McCarty & Fritz Bronner
00003 
00004     This program is free software; you can redistribute it and/or modify
00005     it under the terms of the GNU General Public License as published by
00006     the Free Software Foundation; either version 2 of the License, or
00007     (at your option) any later version.
00008 
00009     This program is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012     GNU General Public License for more details.
00013 
00014     You should have received a copy of the GNU General Public License
00015     along with this program; if not, write to the Free Software
00016     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 */
00018 // Interplay's BUZZ ALDRIN's RACE into SPACE
00019 //
00020 // Formerly -=> LiftOff : Race to the Moon :: IBM version MCGA
00021 // Copyright 1991 by Strategic Visions, Inc.
00022 // Designed by Fritz Bronner
00023 // Programmed by Michael K McCarty
00024 //
00025 #include "Buzz_inc.h"
00026 #include "externs.h"
00027 #include "mis.h"
00028 #include "av.h"
00029 
00030   Equipment *MH[2][8];   // Pointer to the hardware
00031   struct MisAst MA[2][4];  //[2][4]
00032   struct MisEval Mev[60];  // was *Mev;
00033   struct mStr Mis;
00034   struct MXM *AList;
00035   REPLAY Rep;
00036   extern char BIG;
00037 
00038   char pCnt,tMen;     // Counter for pAry
00039   int pAry[15]; // Array for Presige Firsts compelted
00040 
00041   char MANNED[2],CAP[2],LM[2],DOC[2],EVA[2],STEP,FINAL,JOINT,pal2[768],PastBANG,mcc;
00042   char fEarly; /**< kind of a boolean indicating early missions */
00043   char hero,DMFake;
00044   extern char STEPnum;
00045   extern char pNeg[NUM_PLAYERS][MAX_MISSIONS];
00046   extern char AI[2];
00047   ui16 MisStat;
00048   /* STEP tracks mission step numbers             */
00049   /* FINAL is the ultimate result of safety check */
00050   /* JOINT signals the joint mission code         */
00051 
00052 void VerifyData(void)
00053 {
00054  int i,j;
00055  for (j=0;j<NUM_PLAYERS;j++)
00056    for (i=0;i<7;i++) {
00057       strncpy(Data->P[j].Probe[i].ID,Data->P[j].Probe[i].IDX,2);
00058       strncpy(Data->P[j].Rocket[i].ID,Data->P[j].Rocket[i].IDX,2);
00059       strncpy(Data->P[j].Misc[i].ID,Data->P[j].Misc[i].IDX,2);
00060       strncpy(Data->P[j].Manned[i].ID,Data->P[j].Manned[i].IDX,2);
00061       }
00062    return;
00063 }
00064 
00065 void DrawControl(char plr)
00066 {
00067   FILE *fin;
00068   i32 len;
00069   fin=sOpen("CONTROL.IMG","rb",0);
00070   fread(pal,768,1,fin);
00071   fread(&len,4,1,fin);
00072     Swap32bit(len);
00073   if (plr==1) {
00074     fseek(fin,len,SEEK_CUR);
00075     fread(pal,768,1,fin);
00076     fread(&len,4,1,fin);
00077         Swap32bit(len);
00078   }
00079   fread(vhptr.vptr,len,1,fin);fclose(fin);
00080   PCX_D((char *)vhptr.vptr,(char *)screen,(unsigned) len);
00081   av_need_update_xy(0, 0, MAX_X, MAX_Y);
00082 
00083 }
00084 
00085 void SetW(char ch)
00086 {
00087   int i;
00088   i=0;
00089   while (Mev[i].Name[0]!='W') i++;
00090 
00091   Mev[i].Name[2]=ch;
00092 }
00093 
00094 int Launch(char plr,char mis)
00095 {
00096    int i,j,t,k,mcode,avg,temp=0;
00097    char total;
00098    STEP=FINAL=JOINT=PastBANG=0;
00099    memset(pAry,0x00,sizeof pAry); pCnt=0;  // reset values
00100    MisStat=tMen=0x00;  // clear mission status flags
00101    
00102    remove_savedat("REPLAY.TMP");  // make sure replay buffer isn't there
00103 
00104    if (Data->P[plr].Mission[mis].part==1) return 0;
00105 
00106    memset(buffer,0x00,BUFFER_SIZE);  // Clear Buffer
00107    memset(MH,0x00,sizeof MH);
00108    memset(Mev,0x00,sizeof Mev);
00109 
00110    if (Data->P[plr].Mission[mis].MissionCode==2) Data->P[plr].Mission[mis].Duration=1;
00111 
00112    MANNED[0]=Data->P[plr].Mission[mis].Men;
00113    MANNED[1]=Data->P[plr].Mission[mis].Joint ? Data->P[plr].Mission[mis+1].Men : 0;
00114 
00115    JOINT = Data->P[plr].Mission[mis].Joint;
00116 
00117    temp=CheckCrewOK(plr,mis);
00118    if (temp==1) //found mission no crews
00119    {
00120     ClrMiss(plr,mis-Data->P[plr].Mission[mis].part); 
00121    }
00122   
00123    if (!AI[plr] && Data->P[plr].Mission[mis].MissionCode!=0) MisAnn(plr,mis);
00124 
00125    if (Data->P[plr].Mission[mis].MissionCode==0) return -20;
00126    MissionSetup(plr,mis);
00127 
00128    // ****************************************
00129    // Do all Manned Associated Stuff
00130 
00131    memset(MA,0x00,sizeof MA);
00132 
00133    for (i=0;i<(1+JOINT);i++) {
00134       // Decide who to use for each pad
00135           Data->P[plr].Mission[mis+i].Crew = ( Data->P[plr].Mission[mis+i].PCrew > 0 ) ?
00136              Data->P[plr].Mission[mis+i].PCrew :  Data->P[plr].Mission[mis+i].BCrew ;
00137        for (j=0;j<MANNED[i];j++) {
00138         t=Data->P[plr].Mission[mis+i].Prog;
00139         k=Data->P[plr].Mission[mis+i].Crew-1;
00140            total=Data->P[plr].Crew[t][k][j]-1;
00141         MA[i][j].A=&Data->P[plr].Pool[total];
00142         MA[i][j].loc=i;
00143          } 
00144       }
00145 
00146    // Set Mission Status Flag
00147    if (MA[0][0].A!=NULL && MA[1][0].A==NULL) MisStat=S_MAN;
00148    else if (MA[0][0].A==NULL && MA[1][0].A!=NULL) MisStat=JT1_UNMAN|JT2_MAN;
00149    else if (MA[0][0].A!=NULL && MA[1][0].A!=NULL) MisStat=JT1_MAN|JT2_MAN;
00150 
00151    // 0 here is for unused
00152     
00153    CAP[0]=LM[0]=EVA[0]=DOC[0]=CAP[1]=LM[1]=EVA[1]=DOC[1]=-1;
00154 
00155    for (i=0;i<(1+JOINT);i++) {
00156       switch(MANNED[i]) {  
00157           case 0: CAP[i]=LM[i]=EVA[i]=DOC[i]=-1; break;
00158           case 1: CAP[i]=LM[i]=EVA[i]=0;DOC[i]=-1; break;
00159           case 2: CAP[i]=DOC[i]=0;LM[i]=EVA[i]=1; break;  // Last in LM
00160           case 3:
00161                 // LM is always on first mission part!!! :: makes things easier
00162                 if (MH[0][2] && MH[0][2]->ID[1]==0x35) {CAP[i]=0;LM[i]=1;DOC[i]=EVA[i]=2;}
00163                    else {CAP[i]=0;LM[i]=EVA[i]=1;DOC[i]=2;};
00164 
00165               break;
00166           case 4: CAP[i]=0; LM[i]=1; EVA[i]=2; DOC[i]=3; break;
00167           default: break;
00168          };
00169   };
00170   // END MEN SETUP ****************************
00171 
00172   // Do actual Missions
00173 
00174   mcc=mcode=Data->P[plr].Mission[mis].MissionCode;
00175 
00176   // Fixup for Mercury Duration C stuff
00177   if (Data->P[plr].Mission[mis].Hard[Mission_Capsule]==0) 
00178         Data->P[plr].Mission[mis].Duration = minn(2,Data->P[plr].Mission[mis].Duration);
00179 
00180   MissionCodes(plr,mcode,mis);
00181 
00182      /////////////////////////////////////////////////
00183      // Fix for BARIS CD-ROM Planetary Steps (Step W)
00184      // E=moon ; M= mars ;S = saturn; V=venus; J= jupiter  R= Mercury
00185      // Must be at .Name[2]
00186      //
00187      // Search for Step 'W' on planetary steps
00188      //
00189 
00190   if (mcode==7) SetW('E');
00191   else if (mcode==9) SetW('V');
00192   else if (mcode==10) SetW('M');
00193   else if (mcode==11) SetW('R');
00194   else if (mcode==12) SetW('J');
00195   else if (mcode==13) SetW('S');
00196 
00197 //  if (mcode>15 && NOCOPRO && !AI[plr]) MisPrt();
00198 
00199   // Exit missions early
00200   /** \todo The "early" missions should be defined in a file */
00201   fEarly=(!Mis.Days && !(mcode==1 || mcode==7 || mcode==8 || mcode==9 || mcode==11));
00202 
00203   STEPnum=STEP;
00204   if (NOFAIL==1) MisPrt();
00205 
00206   MisDur(plr,Data->P[plr].Mission[mis].Duration);
00207   if (MANNED[0]>0 || MANNED[1]>0 || mcode==1 || mcode==7 || mcode==8)
00208     MisSkip(plr,Find_MaxGoal());
00209 
00210   MisRush(Data->P[plr].Mission[mis].Rushing);
00211   STEPnum=0;
00212 
00213   if (!AI[plr] && BIG==0) {
00214       DrawControl(plr);
00215       FadeIn(2,pal,10,0,0);
00216       }
00217    else 
00218         if (BIG==1) gxClearDisplay(0, 0);
00219 
00220 #define fpf(a,b) fprintf(a,#b ": %d\n",b)
00221 
00222     memset(&Rep, 0x00, sizeof Rep);    // Clear Replay Data Struct
00223 
00224     /* whatever this mcode means... */
00225     if (!AI[plr] && mcode >= 53 )
00226     {
00227         avg = temp = 0;
00228 
00229         for (i = 0; Mev[i].loc != 0x7f; ++i)
00230         {
00231             /* Bugfix -> We need to skip cases when Mev[i].E is NULL */
00232             /* Same solution as used in mis_m.c (MisCheck):207 */
00233             if (!Mev[i].E)
00234                 continue;
00235 
00236             avg += Mev[i].E->MisSaf + Mev[i].asf;
00237             temp += 1;
00238         };
00239 
00240         if (temp)
00241             avg /= temp;
00242         else
00243             avg = 0;
00244 
00245         if (avg >= 3 && avg <= 105)
00246             SafetyRecords(plr, avg);
00247     }
00248 
00249 //   if (!AI[plr]) {PreLoadMusic(M_ELEPHANT); PlayMusic(0);}
00250 
00251    if ((Data->Def.Lev1 == 0 && Data->Def.Lev2 ==2) || (Data->Def.Lev2 == 0 && Data->Def.Lev1==2))
00252      xMODE |= PUSSY; //set easy flag
00253 
00254    if (AI[plr]) xMODE &= ~xMODE_PUSSY;  // map out computer from really easy level
00255 
00256 
00257    MisCheck(plr,mis);  // Mission Resolution
00258 
00259    xMODE &= ~xMODE_PUSSY;
00260 
00261 //   if (!AI[plr]) KillMusic();
00262 
00263    if (Mis.Days==0) total=U_AllotPrest(plr,mis);   // Unmanned Prestige
00264    else total=AllotPrest(plr,mis);                    // Manned Prestige
00265 
00266    total=total-(pNeg[plr][mis]*3);
00267 
00268    Data->P[plr].Prestige+=total;
00269    MissionSetDown(plr,mis);
00270    MissionPast(plr,mis,total);
00271    // Update the Astro's
00272 
00273     for (i = 0; i < 1 + JOINT; i++)
00274     {
00275         /* XXX: was MANNED[i]+1, but why? */
00276         for (j = 0; j < MANNED[i]; j++)
00277         {
00278             if (MA[i][j].A)
00279             {
00280                 if (FINAL >= 100)
00281                     MA[i][j].A->Mis = 1;    // Successful
00282                 else if (Data->P[plr].Other & 4)
00283                     MA[i][j].A->Mis = 2;    // Failure
00284             }
00285         }
00286     }
00287    BIG=0;
00288    return total;
00289 };
00290 
00291 
00292 void MissionPast(char plr,char pad,int prest)
00293 {
00294   int loc,i,j,loop,mc;
00295   FILE *fout,*fin;
00296   unsigned int num;
00297   long size;
00298   char dys[7]={0,2,5,7,12,16,20};
00299 
00300   loc=Data->P[plr].PastMis;
00301   mc=Data->P[plr].Mission[pad].MissionCode;
00302   memset(&Data->P[plr].History[loc],-1,sizeof (struct PastInfo));
00303   strcpy(&Data->P[plr].History[loc].MissionName[0][0],Data->P[plr].Mission[pad].Name);
00304   Data->P[plr].History[loc].Patch[0]=Data->P[plr].Mission[pad].Patch;
00305   if(Data->P[plr].Mission[pad].Joint==1) {
00306       strcpy(&Data->P[plr].History[loc].MissionName[1][0],Data->P[plr].Mission[pad+1].Name);
00307       Data->P[plr].History[loc].Patch[1]=Data->P[plr].Mission[pad+1].Patch;
00308   }
00309 
00310   // Flag for if mission is done
00311   Data->P[plr].History[loc].Event=Data->P[plr].History[loc].Saf=0; 
00312   Data->P[plr].History[loc].Event=(mc==10)?2:((mc==12)?7:((mc==13)?7:0));
00313   if ((mc==10 || mc==12 || mc==13) && prest!=0) Data->P[plr].History[loc].Event=0;
00314   if (MH[0][3])
00315       Data->P[plr].History[loc].Saf=MH[0][3]->MisSaf;
00316   if (!(mc==10 || mc==12 || mc==13)) Data->P[plr].History[loc].Event=Data->P[plr].History[loc].Saf=0; 
00317 
00318   Data->P[plr].History[loc].MissionCode=Data->P[plr].Mission[pad].MissionCode;
00319   Data->P[plr].History[loc].MissionYear=Data->Year;
00320   Data->P[plr].History[loc].Month=Data->P[plr].Mission[pad].Month;
00321   Data->P[plr].History[loc].Prestige=maxx(prest,-10);
00322   Data->P[plr].History[loc].Duration=Data->P[plr].Mission[pad].Duration;
00323   for (loop=0;loop<(Data->P[plr].Mission[pad].Joint+1);loop++) {
00324       i=Data->P[plr].Mission[pad+loop].Prog;
00325       j=Data->P[plr].Mission[pad+loop].Crew-1;
00326       if (Data->P[plr].Mission[pad+loop].Men>0) {
00327           Data->P[plr].History[loc].Man[loop][0]=Data->P[plr].Crew[i][j][0]-1;
00328           Data->P[plr].History[loc].Man[loop][1]=Data->P[plr].Crew[i][j][1]-1;
00329           Data->P[plr].History[loc].Man[loop][2]=Data->P[plr].Crew[i][j][2]-1;
00330           Data->P[plr].History[loc].Man[loop][3]=Data->P[plr].Crew[i][j][3]-1;
00331       } else {
00332           Data->P[plr].History[loc].Man[loop][0]=Data->P[plr].History[loc].Man[loop][1]=
00333               Data->P[plr].History[loc].Man[loop][2]=Data->P[plr].History[loc].Man[loop][3]=-1;
00334       };
00335       if(Data->P[plr].Mission[pad+loop].Men>0) {
00336           for (i=0;i<4;i++) {
00337               j=Data->P[plr].Crew[Data->P[plr].Mission[pad+loop].Prog][Data->P[plr].Mission[pad+loop].Crew-1][i]-1;
00338               if(j>=0) Data->P[plr].Pool[j].MissionNum[Data->P[plr].Pool[j].Missions]=loc;
00339               if(j>=0) {
00340                  Data->P[plr].Pool[j].Missions++;
00341                  Data->P[plr].Pool[j].Prestige+=prest;
00342                  Data->P[plr].Pool[j].Days+=dys[Data->P[plr].Mission[pad+loop].Duration];
00343                  if (hero&0x01) Data->P[plr].Pool[j].Hero=1;
00344                  else if (hero&0x02 && j==EVA[loop]) Data->P[plr].Pool[j].Hero=1;
00345               }   
00346           }
00347       }
00348   };
00349 
00350   for (i=Mission_Capsule; i <= Mission_PrimaryBooster; i++) {
00351       Data->P[plr].History[loc].Hard[0][i]=Data->P[plr].Mission[pad].Hard[i];
00352       if (Data->P[plr].Mission[pad].Joint==1) {
00353           Data->P[plr].History[loc].Hard[1][i]=Data->P[plr].Mission[pad+1].Hard[i];
00354       }
00355   }
00356   Data->P[plr].History[loc].result=FINAL;
00357   Data->P[plr].History[loc].spResult=MaxFail();
00358 
00359   if (Data->P[plr].History[loc].spResult>=4000 && MANNED[0]>0 && MANNED[1]>0) {
00360     // first -all killed
00361      if (MaxFailPad(0)>=4000 && MaxFailPad(1)<4000) {
00362         Data->P[plr].History[loc].spResult=4197;
00363      }
00364     // second -all killed
00365      else if (MaxFailPad(0)<4000 && MaxFailPad(1)>=4000) {
00366         Data->P[plr].History[loc].spResult=4198;
00367      }
00368 
00369     // first and second all killed
00370      else if (MaxFailPad(0)>=4000 && MaxFailPad(1)>=4000) {
00371         Data->P[plr].History[loc].spResult=4199;
00372      }
00373 
00374      if (MANNED[0]>0 && MANNED[1]>0 && tMen==(MANNED[0]+MANNED[1]))
00375        Data->P[plr].History[loc].spResult=4199;
00376 
00377   }
00378   
00379   Rep.Qty=0;
00380   fout=sOpen("REPLAY.TMP","rt",1);
00381   while (!feof(fout)) {
00382      fscanf(fout,"%d\n",&num);
00383      Rep.Off[Rep.Qty++]=num;
00384   };
00385   fclose(fout);
00386   remove_savedat("REPLAY.TMP");
00387   if (Rep.Qty==1 && Data->P[plr].History[loc].spResult<3000) Data->P[plr].History[loc].spResult=1999;
00388 
00389   fin=sOpen("REPLAY.DAT","r+b",1);
00390   size=(plr*100)+Data->P[plr].PastMis;
00391   fseek(fin,size * (sizeof Rep),SEEK_SET);
00392   fwrite(&Rep,sizeof Rep,1,fin);
00393   fclose(fin);
00394 
00395   Data->P[plr].PastMis++;
00396   return;
00397 }
00398 
00399 
00400 int MaxFailPad(char which)
00401 {
00402    int i=0,t=0;
00403    while (i != 0x7f) {
00404      if (Mev[i].pad==which) {
00405        if (Mev[i].StepInfo==0) Mev[i].StepInfo=1003;
00406        t=maxx(Mev[i].StepInfo,t);
00407      }
00408      i=Mev[i].trace;
00409    }
00410    return t;
00411 }
00412 
00413 /* vim: set noet ts=4 sw=4 tw=77: */

Generated on Fri Sep 28 00:35:45 2007 for raceintospace by  doxygen 1.5.3