/* ** cia.c Taken from Hugh Lampert's October 1980 CLoad Game, ** which was written in TRS-80 Level II Basic by: ** Hugh Lampert ** 110 Linder Pl. ** Malverne, NY 11565 ** ** Converted to C by Will Menninger, March 2003. ** Tried to be faithful to the original. Fixed ** a couple idiosyncracies and some grammar/spelling. ** Also added ability to load and save the game. ** */ #include #include #include #include #include typedef struct { char *description; char *shortname; int location; } OBJECT; typedef struct { char *description; int adjacent_location[4]; /* 0=N, 1=S, 2=E, 3=W */ } LOCATION; #define NOBJECTS 50 #define NOBJ2 46 #define NLOCATIONS 30 typedef struct { char name[64]; int elevator_floor; int guard_status; int have_drugged_coffee; int guard_sleep_level; int monitors_on; int elevator_operational; int sculpture_openable; int battery_inserted; int television_connected; int wearing_gloves; int painting_found; int rope_on_hook; int floor_wired; int tape_inserted; int turn_number; int iloc; int nobj; char combination[6]; OBJECT object[NOBJECTS+2]; LOCATION location[NLOCATIONS+2]; } GAMESTAT; static char *textbar = ">--------------------------------------------------------------<"; static OBJECT object[NOBJECTS+2]= { {"dummy entry","xxx",0}, {"a video cassette recorder","rec",2}, {"a video tape","tap",0}, {"a large battery","bat",0}, {"a blank credit card","car",0}, {"an electronic lock","loc",0}, {"an elaborate paper weight","wei",5}, {"a locked wooden door","doo",4}, {"an open wooden door","doo",0}, {"a solid looking door","doo",10}, {"an open door","doo",0}, {"an alert security guard","gua",10}, {"a sleeping security guard","gua",0}, {"a locked maintenance closet","clo",14}, {"a maintenance closet","clo",0}, {"a plastic bag","bag",13}, {"an old-fashioned key","key",9}, {"a small metal square on the wall","squ",16}, {"a lever on the square","lev",16}, {"an old mahogany desk","des",5}, {"a broom","bro",13}, {"a dustpan","dus",13}, {"a spiral notebook","not",0}, {"a mahogany drawer","dra",0}, {"a glass case on a pedestal","cas",6}, {"a razor blade","bla",27}, {"a very large ruby","rub",0}, {"a sign on the square","sig",16}, {"a quarter","qua",0}, {"a coffee machine","mac",8}, {"a cup of steaming hot coffee","cup",0}, {"a small capsule","cap",0}, {"a large scuplture","scu",3}, {"a tall office building","bui",1}, {"a pair of sliding doors","doo",3}, {"a large button on the wall","but",29}, {"a panel of buttons numbered one thru three","pan",9}, {"a strong nylon rope","rop",17}, {"a large hook with a rope hanging from it","hoo",21}, {"a C.I.A. identification badge","bad",-1}, {"a portable television","tel",7}, {"a bank of monitors","mon",7}, {"a chaos I.D. card","car",30}, {"a bank of monitors","mon",19}, {"a small painting","pai",23}, {"a pair of rubber gloves","glo",13}, {"a box with a button on it","box",24}, {"one","one",9}, {"two","two",9}, {"three","thr",9}, {"slit","sli",10}, {"","",0} }; static LOCATION location[NLOCATIONS+2] = { {"dummy entry",{0,0,0,0}}, {"on a busy street",{0,0,0,0}}, {"in a visitor's room",{0,0,3,0}}, {"in the lobby of the building",{1,0,4,2}}, {"in a dingy ante room",{0,0,0,3}}, {"in the company president's office",{0,0,0,4}}, {"in a small sound-proofed cubicle",{0,12,0,0}}, {"in a security office",{0,0,8,0}}, {"in a small hallway",{0,14,9,7}}, {"in a small room",{3,0,0,0}}, {"in a short corridor",{0,15,0,9}}, {"in a hallway made of metal",{0,0,12,10}}, {"in a small plain room",{6,0,0,11}}, {"in a maintenance closet",{0,0,14,0}}, {"in a cafeteria",{8,0,0,0}}, {"in a side corridor",{10,0,16,0}}, {"in a power generator room",{0,0,0,15}}, {"in a sub-basement below the chute",{0,0,18,0}}, {"in the entrance to the secret complex",{0,20,19,17}}, {"in a secret monitoring room",{0,0,0,18}}, {"on a ledge in front of a metal pit thousands of feet deep",{18,0,0,0}}, {"on the other side of the pit",{0,0,22,0}}, {"in a long corridor",{0,25,23,21}}, {"in a large room",{0,26,0,22}}, {"in a secret laboratory",{0,0,25,0}}, {"in a narrow cross corridor",{22,0,0,24}}, {"in a cross examination room",{23,28,0,0}}, {"in a small bathroom",{0,0,28,0}}, {"in the office of the chief of CHAOS",{26,30,0,27}}, {"in the CHAOS control room",{0,0,30,0}}, {"near the end of the complex",{28,0,0,29}}, {"",{0,0,0,0}} }; static char *commandlist[] = { "go ","get","drop","push","pull","look","insert","open","wear", "read","start","break","cut","throw","connect","quit","bon","inventory", "" }; static char *mission= "\nYour mission, %s, is to recover a ruby that is being\n" "used in top secret government projects as a part in a\n" "laser projector.\n" " You will have a partner who is not too bright and needs\n" "you to tell him what to do. Use two word commands like:\n\n" " get notebook go west look door\n\n" "Some commands use only one word. Example: inventory\n" "Two special commands: s (save the game)\n" " l (load a game)\n" " If you want to see changes in your surroundings, type: look\n" "The ruby has been captured by a secret spy ring known as\n" "CHAOS. We suspect they are under cover somewhere in this\n" "neighborhood. Good luck!\n"; static int gamestat_proc_request(GAMESTAT *gs,char *word1,char *word2,int ur); static int gamestat_drop_object(GAMESTAT *gs,char *word2,int iobj); static int gamestat_get_object(GAMESTAT *gs,char *word2,int iobj); static int gamestat_go_check(GAMESTAT *gs,char *word2); static int gamestat_object_is_useable(GAMESTAT *gs,char *word2,int *iobj); static int gamestat_push_object(GAMESTAT *gs,char *word2,int iobj); static int gamestat_pull_object(GAMESTAT *gs,char *word2,int iobj); static int gamestat_look_object(GAMESTAT *gs,char *word2,int iobj); static int gamestat_put_object(GAMESTAT *gs,char *word2,int iobj); static int gamestat_open_object(GAMESTAT *gs,char *word2,int iobj); static int gamestat_wear_object(GAMESTAT *gs,char *word2,int iobj); static int gamestat_read_object(GAMESTAT *gs,char *word2,int iobj); static int gamestat_start_object(GAMESTAT *gs,char *word2,int iobj); static int gamestat_break_object(GAMESTAT *gs,char *word2,int iobj); static int gamestat_cut_object(GAMESTAT *gs,char *word2,int iobj); static int gamestat_throw_object(GAMESTAT *gs,char *word2,int iobj); static int gamestat_connect_object(GAMESTAT *gs,char *word2,int iobj); static void gamestat_inventory(GAMESTAT *gs); static void get_second_word(char *dst,char *src); static int play_again(void); static int gamestat_moverequest(GAMESTAT *gs,char *buf,char *buf2); static int parse_user_input(char *buf); static int gamestat_evaluate_situation(GAMESTAT *gs); static void gamestat_describe_location(GAMESTAT *gs,int nodir); static void gamestat_init(GAMESTAT *gs); static void time_delay(int seconds); static int xstricmp(char *s1,char *s2); static int xstrnicmp(char *s1,char *s2,int n); static void xstrlwr(char *d,char *s,int maxlen); static void clean_line(char *buf); int main(void) { static GAMESTAT _gs; GAMESTAT *gs; time_t now; int i,status,ur,nodir,mro; char buf[128],buf2[128]; time(&now); srand(now); gs=&_gs; gamestat_init(gs); printf("\nC.I.A. Adventure\n\n" "Originally by Hugh Lampert (for TRS-80), Oct. 1980 C-Load Magazine.\n" " http://www.wurb.com/if/game/497\n" "Converted to C by Will Menninger, March, 2003.\n" " http://willus.com/archive\n"); nodir=0; mro=0; while (1) { if (!mro) { gamestat_describe_location(gs,nodir); nodir=0; status=gamestat_evaluate_situation(gs); if (status==0 || status==-10) { if (status==-10) { time_delay(1); printf("I'm dead!\nYou didn't win.\n"); } else printf("You win!\n"); if (play_again()) { gamestat_init(gs); continue; } else break; } if (status==-1) continue; for (gs->nobj=0,i=1;i<=NOBJ2;i++) if (gs->object[i].location==-1) gs->nobj++; } mro=0; ur=gamestat_moverequest(gs,buf,buf2); status=gamestat_proc_request(gs,buf,buf2,ur); if (status==-1) /* Quit */ break; if (status==-2) /* Look */ continue; if (status==-3) { nodir=1; continue; } if (status==-4) { mro=1; continue; } if (status==-10) { time_delay(1); printf("I'm dead!\nYou didn't win.\n"); if (play_again()) { gamestat_init(gs); continue; } else break; } } return(0); } static int gamestat_proc_request(GAMESTAT *gs,char *word1,char *word2,int ur) { int iobj; char buf[16]; printf("\n"); if (!xstrnicmp(word1,"qui",3)) { printf("What? You would leave me here to die alone?\n" "Just for that, I'm going to destroy this game.\n\n"); time_delay(1); printf("\n\n" "BOOOOOOOOOOOOOM!\n"); time_delay(1); printf("\nPress to exit.\n"); fgets(buf,10,stdin); return(-1); } if (!xstrnicmp(word1,"bon",3)) { if (gs->iloc==14) { printf("Whoops! A trap door opened beneath me and\n" "I find myself falling.\n"); time_delay(3); gs->iloc=17; return(-2); } printf("Nothing happened.\n"); return(-3); } if (!xstrnicmp(word1,"inv",3)) { gamestat_inventory(gs); return(-3); } if (!xstrnicmp(word1,"loo",3) && word2[0]=='\0') return(-2); if (word2[0]=='\0') { printf("Please use two word commands so I can understand you.\n"); return(-4); } if (!xstricmp(word2,"1")) strcpy(word2,"one"); if (!xstricmp(word2,"2")) strcpy(word2,"two"); if (!xstricmp(word2,"3")) strcpy(word2,"three"); for (iobj=1;iobjobject[iobj].shortname,3)) break; if (iobj>=NOBJECTS) iobj=0; if (iobj==0 && xstrnicmp(word2,"nor",3) && xstrnicmp(word2,"sou",3) && xstrnicmp(word2,"eas",3) && xstrnicmp(word2,"wes",3)) { printf("I don't know what it is you are talking about.\n"); return(-4); } switch (ur) { case 1: return(gamestat_go_check(gs,word2)); case 2: return(gamestat_get_object(gs,word2,iobj)); case 3: return(gamestat_drop_object(gs,word2,iobj)); case 4: return(gamestat_push_object(gs,word2,iobj)); case 5: return(gamestat_pull_object(gs,word2,iobj)); case 6: return(gamestat_look_object(gs,word2,iobj)); case 7: return(gamestat_put_object(gs,word2,iobj)); case 8: return(gamestat_open_object(gs,word2,iobj)); case 9: return(gamestat_wear_object(gs,word2,iobj)); case 10: return(gamestat_read_object(gs,word2,iobj)); case 11: return(gamestat_start_object(gs,word2,iobj)); case 12: return(gamestat_break_object(gs,word2,iobj)); case 13: return(gamestat_cut_object(gs,word2,iobj)); case 14: return(gamestat_throw_object(gs,word2,iobj)); case 15: return(gamestat_connect_object(gs,word2,iobj)); } return(0); } static int gamestat_drop_object(GAMESTAT *gs,char *word2,int iobj) { int i; for (i=1;i<=NOBJ2;i++) if (!xstrnicmp(word2,gs->object[i].shortname,3) && gs->object[i].location==-1) break; if (i>NOBJ2) { printf("I don't seem to be carrying it.\n"); return(-3); } if (i==30) { printf("I dropped the cup, but it broke into small pieces.\n" "The coffee soaked into the ground.\n"); gs->object[30].location=0; gs->have_drugged_coffee=0; return(-3); } if (i==45) gs->wearing_gloves=0; if (i==31 && gs->object[30].location==-1) { printf("O.K. I dropped it.\n" "But it fell in the coffee!\n"); gs->object[31].location=0; gs->have_drugged_coffee=1; return(-3); } printf("O.K. I dropped it.\n"); gs->object[i].location=gs->iloc; return(-3); } static int gamestat_get_object(GAMESTAT *gs,char *word2,int iobj) { static int getable[23]={2,3,4,6,15,16,20,21,22,23,25,26,27,28, 30,31,37,39,40,42,44,45,46}; int i; if (!gamestat_object_is_useable(gs,word2,&iobj)) return(-3); for (i=0;i<23;i++) if (iobj==getable[i]) break; if (i>=23) { printf("I can't carry that!\n"); return(-3); } i=getable[i]; if (gs->object[i].location==-1) { printf("I already have it.\n"); return(-3); } if (gs->nobj >= 5) { printf("I can't carry anymore.\n"); return(-3); } printf("O.K.\n"); gs->object[i].location=-1; if (!xstrnicmp(word2,"pai",3) && !gs->painting_found) { gs->painting_found=1; gs->object[31].location=gs->iloc; printf("Something fell from the frame!\n"); } if (!xstrnicmp(word2,"tel",3)) gs->television_connected=0; return(-3); } static int gamestat_go_check(GAMESTAT *gs,char *word2) { int i; static char *nogo="I can't go that way at the moment.\n"; if (!xstrnicmp(word2,"nor",3) && gs->location[gs->iloc].adjacent_location[0]>0) { gs->iloc = gs->location[gs->iloc].adjacent_location[0]; return(-2); } if (!xstrnicmp(word2,"sou",3) && gs->location[gs->iloc].adjacent_location[1]>0) { gs->iloc = gs->location[gs->iloc].adjacent_location[1]; return(-2); } if (!xstrnicmp(word2,"eas",3) && gs->location[gs->iloc].adjacent_location[2]>0) { gs->iloc = gs->location[gs->iloc].adjacent_location[2]; return(-2); } if (!xstrnicmp(word2,"wes",3) && gs->location[gs->iloc].adjacent_location[3]>0) { gs->iloc = gs->location[gs->iloc].adjacent_location[3]; return(-2); } if (!xstrnicmp(word2,"nor",3) || !xstrnicmp(word2,"sou",3) || !xstrnicmp(word2,"eas",3) || !xstrnicmp(word2,"wes",3)) { printf("%s",nogo); return(-3); } if (!gamestat_object_is_useable(gs,word2,&i)) return(-3); if (i==8) { gs->iloc=5; return(-2); } if (i==37 && gs->iloc==20 && gs->rope_on_hook) { gs->iloc=21; return(-2); } if (i==10) { gs->iloc=11; return(-2); } if (i==14) { gs->iloc=13; return(-2); } if (i==33) { gs->iloc=3; return(-2); } if (i==34 && gs->elevator_operational) { gs->iloc=9; return(-2); } printf("%s",nogo); return(-3); } static int gamestat_object_is_useable(GAMESTAT *gs,char *word2,int *iobj) { int i; for (i=1;gs->object[i].description[0]!='\0';i++) if (!xstrnicmp(word2,gs->object[i].shortname,3) && (gs->object[i].location==gs->iloc || gs->object[i].location==-1)) break; if (gs->object[i].description[0]=='\0') { printf("I don't see that here.\n"); return(0); } (*iobj)=i; return(1); } static int gamestat_push_object(GAMESTAT *gs,char *word2,int iobj) { if (!xstrnicmp(word2,"but",3) && gs->iloc==3 && !gs->elevator_operational) { gs->elevator_operational=1; printf("The doors open with a whoosh!\n"); return(-3); } if (gs->object[46].location==-1 && !xstrnicmp(word2,"but",3)) { printf("I push the button on the box and ...\n"); time_delay(1); } else { if (!gamestat_object_is_useable(gs,word2,&iobj)) return(-3); if (iobj==17 && !gs->wearing_gloves) { printf("There's electricity coarsing through the square!\n" "I'm being electrocuted!\n"); return(-10); } if (iobj==35 && gs->monitors_on) { printf("The button on the wall goes in .....\n" "CLICK! Something seems different now.\n"); gs->monitors_on=0; return(-3); } if ((iobj==47 && gs->elevator_floor!=1) || (iobj==48 && gs->elevator_floor!=2) || (iobj==49 && gs->elevator_floor!=3)) { static int newroom[3]={3,8,10}; gs->location[9].adjacent_location[0]=newroom[iobj-47]; gs->elevator_floor=iobj-46; printf("The door close and I feel as if the room is moving.\n"); time_delay(2); printf("Suddenly the doors open again.\n"); return(-2); } } if (gs->object[46].location==-1 && (gs->iloc==6 || gs->iloc==29)) { printf("There is a blinding flash....\n"); time_delay(3); gs->iloc=1; gs->elevator_floor=1; gs->location[9].adjacent_location[0]=3; return(-2); } printf("Nothing happens.\n"); return(-3); } static int gamestat_pull_object(GAMESTAT *gs,char *word2,int iobj) { if (!gamestat_object_is_useable(gs,word2,&iobj)) return(-3); if (iobj==18 && !gs->wearing_gloves) { printf("The lever has electricity coarsing through it!\n" "I'm being electrocuted!\n"); return(-10); } if (iobj==18 && gs->floor_wired) { printf("The lever goes all the way up and clicks.\n" "Something seems different now.\n"); gs->floor_wired=0; return(-3); } printf("Nothing happens.\n"); return(-3); } static int gamestat_look_object(GAMESTAT *gs,char *word2,int iobj) { static char *nothing="I see nothing of interest.\n"; if (gs->iloc==5 && !xstrnicmp(word2,"drawer",3)) { printf("It looks fragile.\n"); return(-3); } if (!gamestat_object_is_useable(gs,word2,&iobj)) return(-3); switch (iobj) { case 1: if (!gs->battery_inserted) { printf("There's no power for it.\n"); break; } if (!gs->television_connected) { printf("There's no T.V. to watch on.\n"); break; } printf("%s",nothing); break; case 6: printf("It looks heavy.\n"); break; case 7: printf("It's locked.\n"); break; case 13: printf("It's a very strong bag.\n"); break; case 19: printf("I can see a locked drawer in it.\n"); break; case 22: case 27: printf("There's writing on it.\n"); break; case 34: if (gs->elevator_operational) printf("The doors are open.\n"); else printf("There's a button near the doors.\n"); break; case 24: printf("I can see a gleaming stone in it.\n"); break; case 9: printf("There is a small slit near the door.\n"); break; case 41: if (!gs->monitors_on) printf("The screen is dark.\n"); else printf("I see a metal pit thousands of feet deep on one monitor.\n" "On the other side of the pit, I see a large hook.\n"); break; case 43: if (!gs->monitors_on) printf("The screen is dark.\n"); else printf("I see a room with a case on a pedestal in it.\n"); break; case 44: printf("I see a picture of a grinning jackal.\n"); break; default: printf("%s",nothing); break; } return(-3); } static int gamestat_put_object(GAMESTAT *gs,char *word2,int iobj) { static char *nothing="Nothing happened.\n"; char buf[64]; int iobj2; if (!gamestat_object_is_useable(gs,word2,&iobj)) return(-3); if (iobj!=3 && iobj!=2 && iobj!=4 && iobj!=28) { printf("I can't insert that!\n"); return(-3); } printf("Tell me, in one word, into what? "); fgets(buf,60,stdin); clean_line(buf); if (!gamestat_object_is_useable(gs,buf,&iobj2)) return(-3); if (iobj==3 && iobj2==1) { printf("O.K.\n"); gs->battery_inserted=1; gs->object[iobj].location=0; return(-3); } if (iobj==4 && iobj2==50 && gs->guard_sleep_level<=0) { printf("The guard won't let me!\n"); return(-3); } if (iobj==2 && iobj2==1) { printf("O.K. The tape is in the recorder.\n"); gs->object[iobj].location=0; gs->tape_inserted=1; return(-3); } if (iobj==4 && iobj2==50) { printf("Pop! A section of the wall opens.....\n" "revealing something very interesting.\n"); gs->object[iobj].location=0; gs->object[5].location=gs->iloc; return(-3); } if (iobj==28 && iobj2==29) { printf("Pop! A cup of coffee comes out of the machine.\n"); gs->object[iobj].location=0; gs->object[30].location=gs->iloc; return(-30); } printf("%s",nothing); return(-3); } static int gamestat_open_object(GAMESTAT *gs,char *word2,int iobj) { char buf[64]; if (!xstrnicmp(word2,"drawer",3) && gs->iloc==5 && gs->object[23].location==0) { printf("It's stuck.\n"); return(-3); } if (!gamestat_object_is_useable(gs,word2,&iobj)) return(-3); if (iobj!=7 && iobj!=9 && iobj!=13 && iobj!=15 && iobj!=23 && iobj!=32 && iobj!=5) { printf("I can't open that!\n"); return(-3); } if (iobj==7 && gs->object[16].location==-1) { printf("O.K. I opened the door.\n"); gs->object[iobj].location=0; gs->object[8].location=4; return(-3); } if (iobj==9) { printf("I can't. It doesn't work.\n"); return(-3); } if (iobj==13 && gs->object[16].location==-1) { printf("O.K. The closet is opened.\n"); gs->object[iobj].location=0; gs->object[14].location=14; return(-3); } if (iobj==15) { printf("I can't. It's too strong.\n"); return(-3); } if (iobj==23) { printf("It's stuck.\n"); return(-3); } if (iobj==32 && gs->object[28].location==0 && gs->object[4].location==0 && gs->sculpture_openable) { printf("I open the sculpture.\n" "Something falls out.\n"); gs->object[28].location=gs->iloc; gs->object[4].location=gs->iloc; return(-3); } if (iobj!=5) { printf("I can't do that......yet!\n"); return(-3); } printf("What's the combination? "); fgets(buf,120,stdin); clean_line(buf); if (!xstricmp(buf,gs->combination)) { printf("The door is slowly opening.\n"); gs->object[iobj].location=0; gs->object[9].location=0; gs->object[10].location=10; return(-3); } printf("You must have the wrong combination or you are not\n" "saying it right.\n"); return(-3); } static int gamestat_wear_object(GAMESTAT *gs,char *word2,int iobj) { if (!gamestat_object_is_useable(gs,word2,&iobj)) return(-3); if (!xstrnicmp(word2,"glove",3) && gs->object[45].location==-1) { printf("O.K. I'm now wearing the gloves.\n"); gs->wearing_gloves=1; return(-3); } printf("I can't wear that!\n"); return(-3); } static int gamestat_read_object(GAMESTAT *gs,char *word2,int iobj) { if (!gamestat_object_is_useable(gs,word2,&iobj)) return(-3); if (xstrnicmp(word2,"sign",3) && xstrnicmp(word2,"note",3)) { printf("I can't read that.\n"); return(-3); } if (iobj==22) { printf("It says:\n" "%s,\n" " We have discovered one of CHAOS's secret words.\n" "It is: Bond-007-\n" "It is to be used in a -tasteful- situation.\n",gs->name); return(-3); } if (iobj==27) { printf("It says: Watch out! Dangerous!\n"); return(-3); } printf("I can't read that.\n"); return(-3); } static int gamestat_start_object(GAMESTAT *gs,char *word2,int iobj) { if (!gamestat_object_is_useable(gs,word2,&iobj)) return(-3); if (xstrnicmp(word2,"rec",3)) { printf("I can't start that.\n"); return(-3); } if (!gs->battery_inserted || gs->television_connected!=1 || !gs->tape_inserted) { printf("Nothing happened.\n"); return(-3); } printf("The recorder starts up and presents a short message:\n" "%s,\n" "We have uncovered a number that may help you.\n" "That number is: %s. Please watch out for hidden traps.\n" "Also, there is something in the sculpture.\n", gs->name,gs->combination); gs->sculpture_openable=1; return(-3); } static int gamestat_break_object(GAMESTAT *gs,char *word2,int iobj) { if (xstrnicmp(word2,"drawer",3)) { if (!gamestat_object_is_useable(gs,word2,&iobj)) return(-3); printf("I'm trying to break it, but I can't.\n"); return(-3); } if (gs->object[6].location!=-1) { printf("I can't do that yet.\n"); return(-3); } if (gs->iloc==5) { printf("It's hard....but I got it. Two things fell out.\n"); gs->object[3].location=gs->iloc; gs->object[22].location=gs->iloc; gs->object[23].location=gs->iloc; return(-3); } printf("Nothing happens.\n"); return(-3); } static int gamestat_cut_object(GAMESTAT *gs,char *word2,int iobj) { if (!gamestat_object_is_useable(gs,word2,&iobj)) return(-3); if (iobj!=15 && iobj!=24) { printf("I'm trying. It doesn't work.\n"); return(-3); } if (gs->object[25].location!=-1) { printf("I can't do that yet.\n"); return(-3); } if (iobj==15) { printf("Rip! The bag goes to pieces, and something falls out!\n"); gs->object[iobj].location=0; gs->object[2].location=gs->iloc; return(-3); } printf("I cut the case and reach in to pull something out.\n"); gs->object[26].location=-1; return(-3); } static int gamestat_throw_object(GAMESTAT *gs,char *word2,int iobj) { static char buf[128]; if (!gamestat_object_is_useable(gs,word2,&iobj)) return(-3); if (xstrnicmp(word2,"rop",3)) { printf("I can't throw that.\n"); return(-3); } if (gs->object[37].location!=-1) { printf("I can't do that yet.\n"); return(-3); } printf("Tell me, in one word, at what? "); fgets(buf,120,stdin); clean_line(buf); if (xstrnicmp(buf,"hoo",3)) { printf("O.K. I threw it.\n"); gs->object[37].location=gs->iloc; return(-3); } if (gs->iloc!=20) { printf("I can't do that yet.\n"); return(-3); } printf("I threw the rope and it snagged on the hook.\n"); gs->rope_on_hook=1; gs->object[37].location=gs->iloc; return(-3); } static int gamestat_connect_object(GAMESTAT *gs,char *word2,int iobj) { if (!gamestat_object_is_useable(gs,word2,&iobj)) return(-3); if (xstrnicmp(word2,"tel",3)) { printf("I can't connect that.\n"); return(-3); } if (gs->object[40].location!=gs->iloc) { printf("I don't see the television here.\n"); return(-3); } if (gs->television_connected==1) { printf("I did that already.\n"); return(-3); } if (gs->iloc!=2) { printf("I can't do that....yet!\n"); return(-3); } printf("O.K. The T.V. is connected.\n"); gs->television_connected=1; return(-3); } static void gamestat_inventory(GAMESTAT *gs) { int objcount,i; printf("We are presently carrying:\n"); for (objcount=0,i=1;i<=NOBJ2;i++) { if (gs->object[i].location!=-1) continue; printf("%s %s",objcount>0 ? ",\n" : "",gs->object[i].description); if (i==45 && gs->wearing_gloves) printf(", which I'm wearing"); objcount++; } if (objcount==0) printf(" Nothing"); printf(".\n"); } static void get_second_word(char *dst,char *src) { int i,j; dst[0]='\0'; for (i=0;src[i]==' ' || src[i]=='\t';i++); if (src[i]=='\0') return; for (;src[i]!=' ' && src[i]!='\t' && src[i]!='\0';i++); if (src[i]=='\0') return; for (;src[i]==' ' || src[i]=='\t';i++); if (src[i]=='\0') return; for (j=0;src[i]!=' ' && src[i]!='\t' && src[i]!='\0';i++) dst[j++]=src[i]; dst[j]='\0'; } static int play_again(void) { char buf[64]; printf("Would you like to try again (y/n)? "); fgets(buf,40,stdin); return(buf[0]=='y' || buf[0]=='Y'); } static int gamestat_moverequest(GAMESTAT *gs,char *buf,char *buf2) { int ur,i,j; static char filename[256]; FILE *f; while (1) { printf("\nWhat do you think we should do? "); fgets(buf,127,stdin); clean_line(buf); if ((!xstrnicmp(buf,"l ",2) || !xstrnicmp(buf,"s ",2)) && strlen(buf)>2) { for (i=2;buf[i]==' ' || buf[i]=='\t';i++); for (j=0;buf[i]!=' ' && buf[i]!='\t' && buf[i]!='\0';i++) filename[j++]=buf[i]; filename[j]='\0'; if (strlen(filename)>0) { f=fopen(filename,tolower(buf[0])=='s' ? "wb" : "rb"); if (f!=NULL) { if (tolower(buf[0])=='s') fwrite(gs,sizeof(GAMESTAT),1,f); else fread(gs,sizeof(GAMESTAT),1,f); fclose(f); if (tolower(buf[0])=='l') { for (i=0;iobject[i].description = object[i].description; gs->object[i].shortname = object[i].shortname; } for (i=0;ilocation[i].description = location[i].description; } printf("\nGame status %s file %s.\n\n", tolower(buf[0])=='s' ? "saved to" : "loaded from", filename); continue; } } printf("\n%s file %s failed!\n\n", tolower(buf[0])=='s' ? "Saving to" : "Loading from", filename); continue; } ur=parse_user_input(buf); if (ur>0) break; if (!ur) printf("I don't know how to do that.\n"); else if (ur==-1) printf(mission,gs->name); } get_second_word(buf2,buf); return(ur); } static int parse_user_input(char *buf) { int i,j; static char buf2[128]; static char *cmdeq[] = { "wal","go ","run","go ","tak","get","car","get", "lea","dro","pre","pus","exa","loo","put","ins", "unl","ope","pla","sta","sma","bre","att","con", "lis","inv","" }; static char *cmdeq2[] = { "n","go north","s","go south","e","go east","w","go west", "i","inv","q","quit","" }; for (j=0;buf[j]==' ' || buf[j]=='\t';j++); for (;buf[j]!=' ' && buf[j]!='\t' && buf[j]!='\0';j++); for (;buf[j]==' ' || buf[j]=='\t';j++); for (i=0;buf[i]!='\0' && buf[i]!='\n';i++); buf[i]='\0'; for (i=0;cmdeq2[i][0]!='\0';i+=2) if (!xstricmp(cmdeq2[i],buf)) { strcpy(buf,cmdeq2[i+1]); break; } for (i=0;cmdeq[i][0]!='\0';i+=2) { if (!xstrnicmp(cmdeq[i],buf,3)) { sprintf(buf2,"%s %s",cmdeq[i+1],&buf[j]); strcpy(buf,buf2); break; } } for (i=0;commandlist[i][0]!='\0';i++) if (!xstrnicmp(commandlist[i],buf,3)) return(i+1); if (!xstrnicmp(buf,"ord",3)) return(-1); return(0); } /* ** Returns -1 if should return to describe_location function. ** -10 if player dies (game over) ** -2 ask player what to do ** 0 Mission successful */ static int gamestat_evaluate_situation(GAMESTAT *gs) { if (gs->iloc==3 && gs->object[39].location<0) { printf("The door man looks at me and then throws me out.\n"); gs->iloc=1; return(-1); } if (gs->iloc==10 && gs->object[42].location!=-1 && gs->object[11].location==gs->iloc) { printf("The guard looks at me suspiciously, then throws me back.\n"); gs->iloc=9; return(-1); } if (gs->iloc==6 && gs->monitors_on) { printf("Sirens go off all around me!\n" "Guards run in and shoot me to death!\n"); return(-10); } if (gs->iloc==11 && gs->floor_wired) { printf("The floor is wired with electricity!\n" "I'm being electrocuted!\n"); return(-10); } if (gs->iloc==10 && gs->object[30].location==-1 && gs->have_drugged_coffee) { printf("The guard takes my coffee\n" "and falls to sleep right away.\n"); gs->guard_sleep_level = 7 + rand()%10; gs->object[11].location=0; gs->object[12].location=10; gs->have_drugged_coffee=0; gs->object[30].location=0; return(-2); } if (gs->guard_sleep_level==0) { printf("I hear a noise like someone is yawning.\n"); gs->object[11].location=10; gs->object[12].location=0; gs->guard_sleep_level=-1; gs->guard_status=-2; return(-2); } if (gs->iloc==1 && gs->object[26].location==-1) { printf("Hooray! You've recovered the ruby!\n"); return(0); } if (gs->turn_number > 375) printf("I think they are on to me....I hear noises.\n"); if (gs->turn_number==400) { printf("Oh no! They caught up to me! Help! They're pulling out guns!\n"); return(-10); } if (gs->turn_number==1) printf("Writing on the wall says:\n" "If you want instructions type: orders please\n"); if (gs->iloc==6 && gs->location[6].adjacent_location[1]!=0) { printf("A secret door slams down behind me!\n"); gs->location[6].adjacent_location[1]=0; return(-2); } if (gs->iloc==10 && gs->guard_status==-2) { printf("The guard draws his gun and shoots me!\n"); return(-10); } return(-2); } static void gamestat_describe_location(GAMESTAT *gs,int nodir) { static char *direction[]={"North","South","East","West"}; int i,count; if (!nodir) { printf("\nWe are %s.\n",gs->location[gs->iloc].description); for (i=1;i<=NOBJ2;i++) if (gs->object[i].location==gs->iloc) printf("I can see %s.\n",gs->object[i].description); for (count=0,i=0;i<4;i++) if (gs->location[gs->iloc].adjacent_location[i] > 0) count++; if (count>0) { printf("We could easily go: "); for (count=0,i=0;i<4;i++) if (gs->location[gs->iloc].adjacent_location[i] > 0) printf("%s ",direction[i]); printf("\n"); } printf("%s\n",textbar); } gs->turn_number++; if (gs->guard_sleep_level > 0) gs->guard_sleep_level--; if (gs->turn_number==1) { printf("Enter your name, partner: "); fgets(gs->name,63,stdin); printf("\n"); clean_line(gs->name); if (gs->name[0]=='\0') strcpy(gs->name,"Partner"); } } static void gamestat_init(GAMESTAT *gs) { int i; for (i=0;iobject[i] = object[i]; for (i=0;ilocation[i] = location[i]; strcpy(gs->name,"Partner"); gs->elevator_floor=1; gs->have_drugged_coffee=0; gs->guard_sleep_level=-1; gs->turn_number=0; gs->monitors_on=1; gs->elevator_operational=0; gs->sculpture_openable=0; gs->battery_inserted=0; gs->television_connected=0; gs->wearing_gloves=0; gs->painting_found=0; gs->rope_on_hook=0; gs->tape_inserted=0; gs->iloc=1; gs->nobj=0; gs->guard_status=0; gs->floor_wired=1; for (i=0;i<5;i++) gs->combination[i] = rand()%10 + '0'; gs->combination[i]='\0'; } static void time_delay(int seconds) { time_t t1,t2; time(&t1); t2=t1; while (t2-t1 < seconds+1) time(&t2); } static int xstricmp(char *s1,char *s2) { static char x1[256]; static char x2[256]; xstrlwr(x1,s1,255); xstrlwr(x2,s2,255); return(strcmp(x1,x2)); } static int xstrnicmp(char *s1,char *s2,int n) { static char x1[256]; static char x2[256]; xstrlwr(x1,s1,255); xstrlwr(x2,s2,255); return(strncmp(x1,x2,n)); } static void xstrlwr(char *d,char *s,int maxlen) { int i; for (i=0;i=0 && (buf[i]==' ' || buf[i]=='\t');i--); buf[i+1]='\0'; for (i=0;buf[i]==' ' || buf[i]=='\t';i++); if (i) { for (j=0;buf[i]!='\0';j++,i++) buf[j]=buf[i]; buf[j]='\0'; } }