/* omega copyright (C) by Laurence Raphael Brothers, 1987,1988,1989 */ /* command2.c */ /* This file contains toplevel commands called from command1.c */ #ifndef MSDOS_SUPPORTED_ANTIQUE #include #include #endif #include "glob.h" /* no op a turn.... */ void rest(void) { if (random_range(20) == 1) { switch(random_range(10)) { case 0: print3(" Time passes slowly.... "); break; case 1: print3(" Tick. Tock. Tick. Tock. "); break; case 2: print3(" Ho Hum. "); break; case 3: print3(" Beauty Sleep. Well, in your case, Ugly Sleep. "); break; case 4: print3(" And with Strange Aeons, even Death may die. "); break; case 5: print3(" La Di Da. "); break; case 6: print3(" Time keeps on tickin' tickin' -- into the future.... "); break; case 7: print3(" Boooring! "); break; case 8: print3(" You think I like watching you sleep? "); break; case 9: print3(" You sure have an early bedtime! "); break; } morewait(); } } /* read a scroll, book, tome, etc. */ void peruse(void) { int index; struct object *obj; clearmsg(); if (Player.status[BLINDED] > 0) print3("You're blind -- you can't read!!!"); else if (Player.status[AFRAID] > 0) print3("You are too afraid to stop to read a scroll!"); else { index = getitem_prompt("Read -- ", SCROLL); if (index == ABORT) setgamestatus(SKIP_MONSTERS); else { obj = Player.possessions[index]; if (obj->objchar != SCROLL) { print3("There's nothing written on "); nprint3(itemid(obj)); } else { nprint1("You carefully unfurl the scroll...."); morewait(); item_use(obj); dispose_lost_objects(1,obj); } } } } void quaff(void) { int index; struct object *obj; clearmsg(); index = getitem_prompt("Quaff -- ", POTION); if (index == ABORT) setgamestatus(SKIP_MONSTERS); else { obj = Player.possessions[index]; if (obj->objchar != POTION) { print3("You can't drink "); nprint3(itemid(obj)); } else { print1("You drink it down.... "); item_use(obj); morewait(); dispose_lost_objects(1,obj); } } } void activate(void) { int index = ABORT; char response; clearmsg(); print1("Activate -- item [i] or artifact [a] or quit [ESCAPE]?"); do response = (char) mcigetc(); while ((response != 'i') && (response != 'a') && (response != ESCAPE)); if (response != ESCAPE) { if (response == 'i') index = getitem_prompt("Activate -- ", THING); else if (response == 'a') index = getitem_prompt("Activate -- ", ARTIFACT); if (index != ABORT) { clearmsg(); print1("You activate it.... "); morewait(); item_use(Player.possessions[index]); } else setgamestatus(SKIP_MONSTERS); } else setgamestatus(SKIP_MONSTERS); } void eat (void) { int index; struct object *obj; clearmsg(); index = getitem_prompt("Eat -- ", FOOD); if (index == ABORT) { setgamestatus(SKIP_MONSTERS); } else { obj = Player.possessions[index]; if ((obj->objchar != FOOD) && (obj->objchar != CORPSE)) { print3("You can't eat "); nprint3(itemid(obj)); } else { if (obj->usef == I_FOOD) Player.food = max(0, Player.food+obj->aux); item_use(obj); dispose_lost_objects(1,obj); if (Current_Dungeon == E_COUNTRYSIDE) { Time += 100; hourly_check(); } } } foodcheck(); } /* search all adjacent spots for secrecy */ void search(int *searchval) { int i; if (Player.status[AFRAID] > 0) print3("You are too terror-stricken to stop to search for anything."); else { if (!gamestatusp(FAST_MOVE)) { setgamestatus(FAST_MOVE); *searchval = Searchnum; } for (i=0;i<9;i++) searchat(Player.x+Dirs[0][i],Player.y+Dirs[1][i]); drawvision(Player.x,Player.y); } } /* pick up a thing where the player is */ void pickup(void) { if (Level->site[Player.x][Player.y].things == NULL) print3("There's nothing there!"); else if (Player.status[SHADOWFORM]) print3("You can't really interact with the real world in your shadowy state."); else pickup_at(Player.x,Player.y); } #ifndef MSDOS_SUPPORTED_ANTIQUE /* floor inventory */ void floor_inv(void) { pol ol = Level->site[Player.x][Player.y].things; setgamestatus(SKIP_MONSTERS); menuclear(); while (ol != NULL) { if (ol->thing == NULL) print3("***Error; null thing on things list***"); else { menuprint(itemid(ol->thing)); menuprint("\n"); } ol = ol->next; } showmenu(); morewait(); xredraw(); } #endif void drop(void) { int index,n; clearmsg(); index = getitem_prompt("Drop -- ", CASH); if (index == ABORT) setgamestatus(SKIP_MONSTERS); else { if (index == CASHVALUE) drop_money(); else if ((! Player.possessions[index]->used) || (! cursed(Player.possessions[index]))) { if (Player.possessions[index]->number == 1) { p_drop_at(Player.x,Player.y,1,Player.possessions[index]); conform_lost_objects(1,Player.possessions[index]); } else { n = getnumber(Player.possessions[index]->number); p_drop_at(Player.x,Player.y,n,Player.possessions[index]); conform_lost_objects(n,Player.possessions[index]); } } else { print3("You can't seem to get rid of: "); nprint3(itemid(Player.possessions[index])); } } calc_melee(); } /* talk to the animals -- learn their languages.... */ void talk(void) { int dx,dy,index=0; char response; struct monster *m; clearmsg(); print1("Talk --"); index = getdir(); if (index == ABORT) setgamestatus(SKIP_MONSTERS); else { dx = Dirs[0][index]; dy = Dirs[1][index]; if ((! inbounds(Player.x+dx, Player.y+dy)) || (Level->site[Player.x+dx][Player.y+dy].creature == NULL)) { print3("There's nothing there to talk to!!!"); setgamestatus(SKIP_MONSTERS); } else { m = Level->site[Player.x+dx][Player.y+dy].creature; menuclear(); strcpy(Str1," Talk to "); strcat(Str1,m->monstring); strcat(Str1,":"); menuprint(Str1); menuprint("\na: Greet."); menuprint("\nb: Threaten."); menuprint("\nc: Surrender."); menuprint("\nESCAPE: Clam up."); showmenu(); do response = menugetc(); while ((response != 'a') && (response != 'b') && (response != 'c') && (response != ESCAPE)); switch(response) { case 'a': monster_talk(m); break; case 'b': threaten(m); break; case 'c': surrender(m); break; default: setgamestatus(SKIP_MONSTERS); break; } } } xredraw(); } /* try to deactivate a trap */ void disarm(void) { int x,y,index=0; pob o; clearmsg(); print1("Disarm -- "); index = getdir(); if (index == ABORT) setgamestatus(SKIP_MONSTERS); else { x = Dirs[0][index]+Player.x; y = Dirs[1][index]+Player.y; if (! inbounds(x,y)) print3("Whoa, off the map..."); else if (Level->site[x][y].locchar != TRAP) print3("You can't see a trap there!"); else { if (random_range(50+difficulty()*5) < Player.dex*2+Player.level*3+Player.rank[THIEVES]*10) { print1("You disarmed the trap!"); if (random_range(100) < Player.dex+Player.rank[THIEVES]*10) { o = ((pob) checkmalloc(sizeof(objtype))); switch(Level->site[x][y].p_locf) { case L_TRAP_DART: *o=Objects[OB_TRAP_DART]; break; case L_TRAP_DISINTEGRATE: *o=Objects[OB_TRAP_DISINTEGRATE]; break; case L_TRAP_SLEEP_GAS: *o=Objects[OB_TRAP_SLEEP]; break; case L_TRAP_TELEPORT: *o=Objects[OB_TRAP_TELEPORT]; break; case L_TRAP_ABYSS: *o=Objects[OB_TRAP_ABYSS]; break; case L_TRAP_FIRE: *o=Objects[OB_TRAP_FIRE]; break; case L_TRAP_SNARE: *o=Objects[OB_TRAP_SNARE]; break; case L_TRAP_ACID: *o=Objects[OB_TRAP_ACID]; break; case L_TRAP_MANADRAIN: *o=Objects[OB_TRAP_MANADRAIN]; break; default: /* DAG can't use free_obj() as object not initialized */ free(o); o = NULL; break; } if (o != NULL) { print2("You manage to retrieve the trap components!"); morewait(); Objects[o->id].known = 1; o->known = 1; gain_item(o); gain_experience(25); } } Level->site[x][y].p_locf = L_NO_OP; Level->site[x][y].locchar = FLOOR; lset(x, y, CHANGED); gain_experience(5); } else if (random_range(10+difficulty()*2) > Player.dex) { print1("You accidentally set off the trap!"); Player.x = x; Player.y = y; p_movefunction(Level->site[x][y].p_locf); } else print1("You failed to disarm the trap."); } } } /* is it more blessed to give, or receive? */ void give(void) { int index; int dx,dy,dindex=0; struct monster *m; pob obj; clearmsg(); print1("Give to monster --"); dindex = getdir(); if (dindex == ABORT) setgamestatus(SKIP_MONSTERS); else { dx = Dirs[0][dindex]; dy = Dirs[1][dindex]; if (! inbounds(Player.x+dx, Player.y+dy)) print3("Whoa, off the map..."); else if (Level->site[Player.x+dx][Player.y+dy].creature == NULL) { print3("There's nothing there to give something to!!!"); setgamestatus(SKIP_MONSTERS); } else { m = Level->site[Player.x+dx][Player.y+dy].creature; clearmsg(); index = getitem_prompt("Give what? ", CASH); if (index == ABORT) setgamestatus(SKIP_MONSTERS); else if (index == CASHVALUE) give_money(m); else if (! cursed(Player.possessions[index])) { obj = copy_obj( Player.possessions[index] ); obj->used = FALSE; conform_lost_objects(1,Player.possessions[index]); obj->number = 1; print2("Given: "); nprint2(itemid(obj)); morewait(); /* WDT bug fix: I moved the print above the givemonster * call. If that turns out looking ugly, I should change it to * a sprintf or strcat. At any rate, it was wrong before because * it was accessing an object which had already been freed as part * of givemonster. */ givemonster(m,obj); calc_melee(); } else { print3("You can't even give away: "); nprint3(itemid(Player.possessions[index])); } } } } /* zap a wand, of course */ void zapwand(void) { int index; struct object *obj; clearmsg(); if (Player.status[AFRAID] > 0) print3("You are so terror-stricken you can't hold a wand straight!"); else { index = getitem_prompt("Zap -- ", STICK); if (index == ABORT) setgamestatus(SKIP_MONSTERS); else { obj = Player.possessions[index]; if (obj->objchar != STICK) { print3("You can't zap: "); nprint3(itemid(obj)); } else if (obj->charge < 1) print3("Fizz.... Pflpt. Out of charges. "); else { obj->charge--; item_use(obj); } } } } /* cast a spell */ void magic(void) { int index,drain; clearmsg(); if (Player.status[AFRAID] > 0) print3("You are too afraid to concentrate on a spell!"); else { index = getspell(); xredraw(); if (index == ABORT) setgamestatus(SKIP_MONSTERS); else { drain = Spells[index].powerdrain; if (Lunarity == 1) drain = drain / 2; else if (Lunarity == -1) drain = drain *2; if (drain > Player.mana) if (Lunarity == -1 && Player.mana >= drain/2) print3("The contrary moon has made that spell too draining! "); else print3("You lack the power for that spell! "); else { Player.mana -= drain; cast_spell(index); } } } dataprint(); } /* go upstairs ('<' command) */ void upstairs(void) { if (Level->site[Player.x][Player.y].locchar != STAIRS_UP) print3("Not here!"); else if (Level->site[Player.x][Player.y].p_locf == L_ESCALATOR) p_movefunction(Level->site[Player.x][Player.y].p_locf); else { if (gamestatusp(MOUNTED)) print2("You manage to get your horse upstairs."); print1("You ascend a level."); if (Level->depth <= 1) { if (Level->environment == E_SEWERS) change_environment(E_CITY); else change_environment(E_COUNTRYSIDE); } else change_level(Level->depth,Level->depth-1,FALSE); roomcheck(); } setgamestatus(SKIP_MONSTERS); } /* go downstairs ('>' command) */ void downstairs(void) { if (Level->site[Player.x][Player.y].locchar != STAIRS_DOWN) print3("Not here!"); else if (Level->site[Player.x][Player.y].p_locf == L_ENTER_CIRCLE || Level->site[Player.x][Player.y].p_locf == L_ENTER_COURT) p_movefunction(Level->site[Player.x][Player.y].p_locf); else { if (gamestatusp(MOUNTED)) print2("You manage to get your horse downstairs."); if (Current_Environment == Current_Dungeon) { print1("You descend a level."); change_level(Level->depth,Level->depth+1,FALSE); roomcheck(); } else if ((Current_Environment == E_CITY) || (Last_Environment == E_CITY)) change_environment(E_SEWERS); else if (Current_Environment != Current_Dungeon) print3("This stairway is deviant. You can't use it."); } setgamestatus(SKIP_MONSTERS); } /* set various player options */ /* have to redefine in odefs for next full recompile */ void setoptions(void) { int slot = 1,to,done = FALSE; int response; clearmsg(); menuclear(); display_options(); move_slot(1,1,NUMOPTIONS); clearmsg(); print1("Currently selected option is preceded by highlit >>"); print2("Move selected option with '>' and '<', ESCAPE to quit."); do { response = mcigetc(); switch(response) { case 'j': case '>': #ifdef KEY_DOWN case KEY_DOWN: #endif to = slot + 1; #ifndef COMPRESS_SAVE_FILES if (to == 8) /* COMPRESS_OPTION */ to = 9; #endif slot = move_slot(slot,to,NUMOPTIONS+1); break; case 'k': case '<': #ifdef KEY_UP case KEY_UP: #endif to = slot - 1; #ifndef COMPRESS_SAVE_FILES if (to == 8) /* COMPRESS_OPTION */ to = 7; #endif if (to > 0) slot = move_slot(slot,to,NUMOPTIONS+1); break; #ifdef KEY_HOME case KEY_HOME: slot = move_slot(slot,1,NUMOPTIONS+1); break; #endif #ifdef KEY_LL case KEY_LL: slot = move_slot(slot,NUMOPTIONS,NUMOPTIONS+1); break; #endif case 't': if (slot <= NUMTFOPTIONS) optionset(pow2(slot-1)); else if (slot == VERBOSITY_LEVEL) Verbosity = TERSE; else print3("'T' is meaningless for this option."); break; case 'f': if (slot <= NUMTFOPTIONS) optionreset(pow2(slot-1)); else print3("'F' is meaningless for this option."); break; case 'm': if (slot == VERBOSITY_LEVEL) Verbosity = MEDIUM; else print3("'M' is meaningless for this option."); break; case 'v': if (slot == VERBOSITY_LEVEL) Verbosity = VERBOSE; else print3("'V' is meaningless for this option."); break; case '1':case '2':case '3':case '4':case '5': case '6':case '7':case '8':case'9': if (slot == SEARCH_DURATION) Searchnum = response - '0'; else print3("A number is meaningless for this option."); break; case ESCAPE: done = TRUE; break; default: print3("That response is meaningless for this option."); break; } display_option_slot(slot); move_slot(slot,slot,NUMOPTIONS+1); } while (! done); if (optionp(SHOW_COLOUR)) colour_on(); else colour_off(); #if !defined(MSDOS_SUPPORTED_ANTIQUE) && !defined(AMIGA) xredraw(); #endif } /* name an item */ void callitem(void) { int index; pob obj; clearmsg(); setgamestatus(SKIP_MONSTERS); index = getitem_prompt("Call -- ", NULL_ITEM); if (index == CASHVALUE) print3("Can't rename cash!"); else if (index != ABORT) { obj = Player.possessions[index]; if (obj->known) print3("That item is already identified!"); else { print1("Call it:"); obj->objstr = salloc(msgscanstring()); clearmsg(); print2("Also call all similar items by that name? [yn] "); if (ynq2() == 'y') { Objects[obj->id].objstr = obj->objstr; } } } } /* open a door */ void opendoor(void) { int dir; int ox,oy; clearmsg(); print1("Open --"); dir = getdir(); if (dir == ABORT) setgamestatus(SKIP_MONSTERS); else { ox = Player.x + Dirs[0][dir]; oy = Player.y + Dirs[1][dir]; if (Level->site[ox][oy].locchar == OPEN_DOOR) { print3("That door is already open!"); setgamestatus(SKIP_MONSTERS); } else if (Level->site[ox][oy].locchar == PORTCULLIS) { print1("You try to lift the massive steel portcullis...."); if (random_range(100) < Player.str) { print2("Incredible. You bust a gut and lift the portcullis."); Level->site[ox][oy].locchar = FLOOR; lset(ox, oy, CHANGED); } else { print2("Argh. You ruptured yourself."); p_damage(Player.str,UNSTOPPABLE,"a portcullis"); } } else if ((Level->site[ox][oy].locchar != CLOSED_DOOR) || loc_statusp(ox,oy,SECRET)) { print3("You can't open that!"); setgamestatus(SKIP_MONSTERS); } else if (Level->site[ox][oy].aux == LOCKED) print3("That door seems to be locked."); else { Level->site[ox][oy].locchar = OPEN_DOOR; lset(ox, oy, CHANGED); } } } /* Try to destroy some location */ void bash_location(void) { int dir; int ox,oy; clearmsg(); print1("Bashing --"); dir = getdir(); if (dir == ABORT) setgamestatus(SKIP_MONSTERS); else { ox = Player.x + Dirs[0][dir]; oy = Player.y + Dirs[1][dir]; if ((Current_Environment == E_CITY) && (ox == 0) && (oy == 0)) { print1("Back Door WIZARD Mode!"); print2("You will invalidate your score if you proceed."); morewait(); if (cinema_confirm("You are about to enable WIZARD Mode.")=='y') { print2("You feel like a cheater."); setgamestatus(CHEATED); } else print2("A sudden tension goes out of the air...."); } else { if (Level->site[ox][oy].locchar == WALL) { print1("You hurl yourself at the wall!"); p_damage(Player.str,NORMAL_DAMAGE,"a suicidal urge"); } else if (Level->site[ox][oy].locchar == OPEN_DOOR) { print1("You hurl yourself through the open door!"); print2("Yaaaaah! ... thud."); morewait(); Player.x = ox; Player.y = oy; p_damage(3,UNSTOPPABLE,"silliness"); p_movefunction(Level->site[Player.x][Player.y].p_locf); setgamestatus(SKIP_MONSTERS); /* monsters are surprised... */ } else if (Level->site[ox][oy].locchar == CLOSED_DOOR) { if (loc_statusp(ox,oy,SECRET)) { print1("You found a secret door!"); lreset(ox,oy,SECRET); lset(ox, oy, CHANGED); } if (Level->site[ox][oy].aux == LOCKED) { if (random_range(50+difficulty()*10) < Player.str) { Player.x = ox; Player.y = oy; print2("You blast the door off its hinges!"); Level->site[ox][oy].locchar = FLOOR; lset(ox, oy, CHANGED); p_movefunction(Level->site[Player.x][Player.y].p_locf); setgamestatus(SKIP_MONSTERS); /* monsters are surprised... */ } else { print1("Crash! The door holds."); if (random_range(30) > Player.str) p_damage(max(1,statmod(Player.str)),UNSTOPPABLE,"a door"); } } else { Player.x = ox; Player.y = oy; print2("You bash open the door!"); if (random_range(30) > Player.str) p_damage(1,UNSTOPPABLE,"a door"); Level->site[ox][oy].locchar = OPEN_DOOR; lset(ox, oy, CHANGED); p_movefunction(Level->site[Player.x][Player.y].p_locf); setgamestatus(SKIP_MONSTERS); /* monsters are surprised... */ } } else if (Level->site[ox][oy].locchar == STATUE) { statue_random(ox,oy); } else if (Level->site[ox][oy].locchar == PORTCULLIS) { print1("Really, you don't have a prayer."); if (random_range(1000) < Player.str) { print2("The portcullis flies backwards into a thousand fragments."); print3("Wow. What a stud."); gain_experience(100); Level->site[ox][oy].locchar = FLOOR; Level->site[ox][oy].p_locf = L_NO_OP; lset(ox, oy, CHANGED); } else { print2("You only hurt yourself on the 3'' thick steel bars."); p_damage(Player.str,UNSTOPPABLE,"a portcullis"); } } else if (Level->site[ox][oy].locchar == ALTAR) { if ((Player.patron > 0)&&(Level->site[ox][oy].aux == Player.patron)) { print1("You have a vision! An awesome angel hovers over the altar."); print2("The angel says: 'You twit, don't bash your own altar!'"); print3("The angel slaps you upside the head for your presumption."); p_damage(Player.hp-1,UNSTOPPABLE,"an annoyed angel"); } else if (Level->site[ox][oy].aux == 0) { print1("The feeble powers of the minor godling are not enough to"); print2("protect his altar! The altar crumbles away to dust."); print3("You feel almost unbearably smug."); Level->site[ox][oy].locchar = RUBBLE; Level->site[ox][oy].p_locf = L_RUBBLE; lset(ox, oy, CHANGED); gain_experience(5); } else { print1("You have successfully annoyed a major deity. Good job."); print2("Zzzzap! A bolt of godsfire strikes!"); if (Player.rank[PRIESTHOOD] > 0) print3("Your own deity's aegis defends you from the bolt!"); p_damage(max(0,random_range(100)-Player.rank[PRIESTHOOD]*20), UNSTOPPABLE, "a bolt of godsfire"); if (Player.rank[PRIESTHOOD]*20+Player.pow+Player.level > random_range(200)) { morewait(); print1("The altar crumbles..."); Level->site[ox][oy].locchar = RUBBLE; Level->site[ox][oy].p_locf = L_RUBBLE; lset(ox, oy, CHANGED); morewait(); if (Player.rank[PRIESTHOOD]) { print2("You sense your deity's pleasure with you."); morewait(); print3("You are surrounded by a golden glow."); cleanse(1); heal(10); } gain_experience(500); } } } else { print3("You restrain yourself from total silliness."); setgamestatus(SKIP_MONSTERS); } } } } /* attempt destroy an item */ void bash_item(void) { int item; pob obj; clearmsg(); item = getitem_prompt("Destroy an item -- ", NULL_ITEM); if (item == ABORT) setgamestatus(SKIP_MONSTERS); else if (item == CASHVALUE) { print3("You can't destroy cash!"); setgamestatus(SKIP_MONSTERS); } else { obj = Player.possessions[item]; if (Player.str+random_range(20) > obj->fragility+random_range(20)) { /* damage_item() can free object, but need these after... */ int oid; unsigned char olevel; olevel = obj->level; oid = obj->id; if ( damage_item(obj) ) { if ( OB_POTION_CHAOS == oid ) { Player.alignment += random_range(10); if ( Player.alignment < 0 ) { print2("You feel a sense of inner constraint!"); gain_experience(olevel * olevel * 5); } else print2("You feel wonderfully lawful!"); /* In either case, chaotic or lawful, destroying a PoCh is * lawful. */ Player.alignment += random_range(10); } else if ( OB_SCROLL_LAW == oid ) { Player.alignment -= random_range(10); if ( Player.alignment < 0 ) { print2("You feel deliciously chaotic!"); gain_experience(olevel * olevel * 5); } else print2("You feel a sense of inner turmoil!"); Player.alignment -= random_range(10); } else if (Player.alignment < 0) { print2("That was fun...."); gain_experience(olevel * olevel * 5); } } } else { if (obj->objchar == WEAPON) { print2("The weapon turned in your hand -- you hit yourself!"); p_damage(random_range(obj->dmg+abs(obj->plus)), NORMAL_DAMAGE, "a failure at vandalism"); } else if (obj->objchar == ARTIFACT) { print2("Uh Oh -- Now you've gotten it angry...."); p_damage(obj->level*10, UNSTOPPABLE, "an enraged artifact"); } else { print2("Ouch! Damn thing refuses to break..."); p_damage(1,UNSTOPPABLE,"a failure at vandalism"); } } } } /* guess what this does */ /* if force is true, exiting due to some problem - don't bomb out */ void save(int compress, int force) { char fname[100]; int pos, ok = TRUE; clearmsg(); if (gamestatusp(ARENA_MODE)) { if (force) { resetgamestatus(ARENA_MODE); change_environment(E_CITY); } else { print3("Can't save the game in the arena!"); setgamestatus(SKIP_MONSTERS); ok = FALSE; } } else if (Current_Environment == E_ABYSS) { if (force) change_environment(E_COUNTRYSIDE); else { print3("Can't save the game in the Adept's Challenge!"); setgamestatus(SKIP_MONSTERS); ok = FALSE; } } else if (Current_Environment == E_TACTICAL_MAP) { if (force) change_environment(E_COUNTRYSIDE); else { /* WDT MARK! I understand this, but it's wrong. */ print3("Can't save the game in the tactical map!"); setgamestatus(SKIP_MONSTERS); ok = FALSE; } } if (!force && ok) { ok = (cinema_confirm("You're about to save and exit.") == 'y'); } if (force || ok) { sprintf(Str1, "Enter savefile name [default %s]: ", SaveFileName ); print1(Str1); strcpy(fname,msgscanstring()); if (fname[0] == '\0') { /* no file name entered, use default. DAG */ strcpy( fname, SaveFileName ); } #ifdef MSDOS for (pos = 0; fname[pos] && isalnum(fname[pos]); pos++) ; #else for (pos = 0; fname[pos] && isprint(fname[pos]) && !isspace(fname[pos]); pos++) ; #endif if (fname[pos]) { sprintf(Str1, "Illegal character '%c' in filename - Save aborted.", fname[pos]); print1(Str1); ok = FALSE; } #ifdef MSDOS if (strlen(fname) > FNAME_MAX_LEN) { /* WDT -- copied from SYSV block below. */ sprintf(Str1, "Save name longer than %d characters - Save aborted.", FNAME_MAX_LEN); print1(Str1); ok = FALSE; } #else # ifdef SYSV if (strlen(fname) > FNAME_MAX_LEN - EXT_LENGTH - 1) { sprintf(Str1, "Save name longer than %d characters - Save aborted.", FNAME_MAX_LEN - EXT_LENGTH - 1); print1(Str1); ok = FALSE; } # endif #endif if (ok) { if (save_game(compress,fname)) { endgraf(); printf("Bye!\n"); exit(0); } else print1("Internal error -- unable to save."); } } if (force) { morewait(); clearmsg(); print1("The game is quitting - you will lose your character."); print2("Try to save again? "); if (ynq2() == 'y') save(compress, force); } setgamestatus(SKIP_MONSTERS); /* if we get here, we failed to save */ } /* close a door */ void closedoor(void) { int dir; int ox,oy; clearmsg(); print1("Close --"); dir = getdir(); if (dir == ABORT) setgamestatus(SKIP_MONSTERS); else { ox = Player.x + Dirs[0][dir]; oy = Player.y + Dirs[1][dir]; if (Level->site[ox][oy].locchar == CLOSED_DOOR) { print3("That door is already closed!"); setgamestatus(SKIP_MONSTERS); } else if (Level->site[ox][oy].locchar != OPEN_DOOR) { print3("You can't close that!"); setgamestatus(SKIP_MONSTERS); } else Level->site[ox][oy].locchar = CLOSED_DOOR; lset(ox, oy, CHANGED); } } /* handle a h,j,k,l, etc. */ void moveplayer(int dx, int dy) { if (p_moveable(Player.x+dx,Player.y+dy)) { if (Player.status[IMMOBILE] > 0) { resetgamestatus(FAST_MOVE); print3("You are unable to move"); } else if ((Player.maxweight < Player.itemweight) && random_range(2) && (! Player.status[LEVITATING])) { if (gamestatusp(MOUNTED)) { print1("Your horse refuses to carry you and your pack another step!"); print2("Your steed bucks wildly and throws you off!"); p_damage(10,UNSTOPPABLE,"a cruelly abused horse"); resetgamestatus(MOUNTED); summon(-1,HORSE); } else { p_damage(1,UNSTOPPABLE,"a rupture"); print3("The weight of your pack drags you down. You can't move."); } } else { Player.x += dx; Player.y += dy; p_movefunction(Level->site[Player.x][Player.y].p_locf); /* causes moves to take effectively 30 seconds in town without monsters being sped up compared to player */ if ((Current_Environment == E_CITY) || (Current_Environment == E_VILLAGE)) { twiddle = ! twiddle; if (twiddle) { Time++; if (Time % 10 == 0) tenminute_check(); else minute_status_check(); } } /* this test protects against player entering countryside and still having effects from being on the Level, a kluge, but hey,... */ if (Current_Environment != E_COUNTRYSIDE) { if (gamestatusp(FAST_MOVE)) if ((Level->site[Player.x][Player.y].things != NULL) || (optionp(RUNSTOP) && loc_statusp(Player.x,Player.y,STOPS))) resetgamestatus(FAST_MOVE); if ((Level->site[Player.x][Player.y].things != NULL) && (optionp(PICKUP))) pickup(); } } } else if (gamestatusp(FAST_MOVE)) { drawvision(Player.x,Player.y); resetgamestatus(FAST_MOVE); } } /* handle a h,j,k,l, etc. */ void movepincountry(int dx, int dy) { int i,takestime = TRUE; if ((Player.maxweight < Player.itemweight) && random_range(2) && (! Player.status[LEVITATING])) { if (gamestatusp(MOUNTED)) { print1("Your horse refuses to carry you and your pack another step!"); print2("Your steed bucks wildly and throws you off!"); p_damage(10,UNSTOPPABLE,"a cruelly abused horse"); resetgamestatus(MOUNTED); morewait(); print1("With a shrill neigh of defiance, your former steed gallops"); print2("off into the middle distance...."); if (Player.packptr != 0) { morewait(); print1("You remember (too late) that the contents of your pack"); print2("were kept in your steed's saddlebags!"); for(i=0;i 0) print3("You are unable to move"); else { Player.x += dx; Player.y += dy; if ((! gamestatusp(MOUNTED))&&(Player.possessions[O_BOOTS] != NULL)) { if (Player.possessions[O_BOOTS]->usef == I_BOOTS_7LEAGUE) { takestime = FALSE; if (Player.possessions[O_BOOTS]->blessing < 0) { print1("Whooah! -- Your boots launch you into the sky...."); print2("You come down in a strange location...."); setPlayerXY( random_range(COUNTRY_WIDTH), random_range(COUNTRY_LENGTH)); morewait(); clearmsg(); print1("Your boots disintegrate with a malicious giggle..."); dispose_lost_objects(1,Player.possessions[O_BOOTS]); } else if (Player.possessions[O_BOOTS]->known != 2) { print1("Wow! Your boots take you 7 leagues in a single stride!"); Player.possessions[O_BOOTS]->known = 2; } } } if (gamestatusp(LOST) && (Precipitation < 1) && c_statusp(Player.x, Player.y, SEEN)) { print3("Ah! Now you know where you are!"); morewait(); resetgamestatus(LOST); } else if (gamestatusp(LOST)) { print3("You're still lost."); morewait(); } if (Precipitation > 0) Precipitation--; c_set(Player.x, Player.y, SEEN); terrain_check(takestime); } } } }