home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
- /* hack.do.c version 1.0.1 - check Levitation with POT_PARALYSIS
- - added flags.no_rest_on_space */
-
- #include <stdio.h>
- #ifndef AMIGA
- #include <signal.h> /* Is this really used??? */
- #endif
- #include <fcntl.h>
- #include "hack.h"
- #include "def.func_tab.h"
-
- extern char *getenv(),*parse(),*getlogin(),*lowc(),*unctrl();
- extern int float_down();
- extern char *nomovemsg, *catmore;
- extern struct obj *splitobj(), *addinv();
- extern boolean hmon();
- extern char morc;
-
- /* Routines to do various user commands */
-
- int done1();
-
- dodrink() {
- register struct obj *otmp,*objs;
- register struct monst *mtmp;
- register int unkn = 0, nothing = 0;
-
- otmp = getobj("!", "drink");
- if(!otmp) return(0);
- switch(otmp->otyp){
- case POT_RESTORE_STRENGTH:
- unkn++;
- pline("Wow! This makes you feel great!");
- if(u.ustr < u.ustrmax) {
- u.ustr = u.ustrmax;
- flags.botl = 1;
- }
- break;
- case POT_BOOZE:
- unkn++;
- pline("Ooph! This tastes like liquid fire!");
- Confusion += d(3,8);
- /* the whiskey makes us feel better */
- if(u.uhp < u.uhpmax) losehp(-1, "bottle of whiskey");
- if(!rn2(4)) {
- pline("You pass out.");
- multi = -rnd(15);
- nomovemsg = "You awake with a headache.";
- }
- break;
- case POT_INVISIBILITY:
- if(Invis)
- nothing++;
- else {
- if(!Blind)
- pline("Gee! All of a sudden, you can't see yourself.");
- else
- pline("You feel rather airy."), unkn++;
- newsym(u.ux,u.uy);
- }
- Invis += rn1(15,31);
- break;
- case POT_FRUIT_JUICE:
- pline("This tastes like fruit juice.");
- lesshungry(20);
- break;
- case POT_HEALING:
- pline("You begin to feel better.");
- flags.botl = 1;
- u.uhp += rnd(10);
- if(u.uhp > u.uhpmax)
- u.uhp = ++u.uhpmax;
- if(Blind) Blind = 1; /* see on next move */
- if(Sick) Sick = 0;
- break;
- case POT_PARALYSIS:
- if(Levitation)
- pline("Your head is frozen to the ceiling!");
- else
- pline("Your feet are frozen to the floor!");
- nomul(-(rn1(10,25)));
- break;
- case POT_MONSTER_DETECTION:
- if(!fmon) {
- strange_feeling(otmp);
- return(1);
- } else {
- cls();
- for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
- if(mtmp->mx > 0)
- at(mtmp->mx,mtmp->my,mtmp->data->mlet);
- prme();
- pline("You sense the presence of monsters.");
- more();
- docrt();
- }
- break;
- case POT_OBJECT_DETECTION:
- if(!fobj) {
- strange_feeling(otmp);
- return(1);
- } else {
- for(objs = fobj; objs; objs = objs->nobj)
- if(objs->ox != u.ux || objs->oy != u.uy)
- goto outobjmap;
- pline("You sense the presence of objects close nearby.");
- break;
- outobjmap:
- cls();
- for(objs = fobj; objs; objs = objs->nobj)
- at(objs->ox,objs->oy,objs->olet);
- prme();
- pline("You sense the presence of objects.");
- more();
- docrt();
- }
- break;
- case POT_SICKNESS:
- pline("Yech! This stuff tastes like poison.");
- if(Poison_resistance)
- pline("(But in fact it was biologically contaminated orange juice.)");
- losestr(rn1(4,3));
- losehp(rnd(10), "poison potion");
- break;
- case POT_CONFUSION:
- if(!Confusion)
- pline("Huh, What? Where am I?");
- else
- nothing++;
- Confusion += rn1(7,16);
- break;
- case POT_GAIN_STRENGTH:
- pline("Wow do you feel strong!");
- if(u.ustr == 118) break;
- if(u.ustr > 17) u.ustr += rnd(118-u.ustr);
- else u.ustr++;
- if(u.ustr > u.ustrmax) u.ustrmax = u.ustr;
- flags.botl = 1;
- break;
- case POT_SPEED:
- if(Wounded_legs) {
- if((Wounded_legs & BOTH_SIDES) == BOTH_SIDES)
- pline("Your legs feel somewhat better.");
- else
- pline("Your leg feels somewhat better.");
- Wounded_legs = 0;
- unkn++;
- break;
- }
- if(!(Fast & ~INTRINSIC))
- pline("You are suddenly moving much faster.");
- else
- pline("Your legs get new energy."), unkn++;
- Fast += rn1(10,100);
- break;
- case POT_BLINDNESS:
- if(!Blind)
- pline("A cloud of darkness falls upon you.");
- else
- nothing++;
- Blind += rn1(100,250);
- seeoff(0);
- break;
- case POT_GAIN_LEVEL:
- pluslvl();
- break;
- case POT_EXTRA_HEALING:
- pline("You feel much better.");
- flags.botl = 1;
- u.uhp += d(2,20)+1;
- if(u.uhp > u.uhpmax)
- u.uhp = (u.uhpmax += 2);
- if(Blind) Blind = 1;
- if(Sick) Sick = 0;
- break;
- case POT_LEVITATION:
- if(!Levitation)
- float_up();
- else
- nothing++;
- Levitation += rnd(100);
- u.uprops[PROP(RIN_LEVITATION)].p_tofn = float_down;
- break;
- default:
- pline("What a funny potion! (%d)", otmp->otyp);
- impossible();
- return(0);
- }
- if(nothing) {
- unkn++;
- pline("You have a peculiar feeling for a moment, then it passes.");
- }
- if(otmp->dknown && !objects[otmp->otyp].oc_name_known) {
- if(!unkn) {
- objects[otmp->otyp].oc_name_known = 1;
- u.urexp += 10;
- } else if(!objects[otmp->otyp].oc_uname)
- docall(otmp);
- }
- useup(otmp);
- return(1);
- }
-
- pluslvl()
- {
- register int num;
-
- pline("You feel more experienced.");
- num = rnd(10);
- u.uhpmax += num;
- u.uhp += num;
- u.uexp = (10*pow(u.ulevel-1))+1;
- pline("Welcome to level %d.", ++u.ulevel);
- flags.botl = 1;
- }
-
- strange_feeling(obj)
- register struct obj *obj;
- {
- pline("You have a strange feeling for a moment, then it passes.");
- if(!objects[obj->otyp].oc_name_known && !objects[obj->otyp].oc_uname)
- docall(obj);
- useup(obj);
- }
-
- dodrop() {
- register struct obj *obj;
-
- obj = getobj("0$#", "drop");
- if(!obj) return(0);
- if(obj->olet == '$') {
- if(obj->quan == 0)
- pline("You didn't drop any gold pieces.");
- else {
- mkgold((int) obj->quan, u.ux, u.uy);
- pline("You dropped %u gold piece%s.",
- obj->quan, plur(obj->quan));
- if(Invis) newsym(u.ux, u.uy);
- }
- free((char *) obj);
- return(1);
- }
- return(drop(obj));
- }
-
- drop(obj) register struct obj *obj; {
- if(obj->owornmask & (W_ARMOR | W_RING)){
- pline("You cannot drop something you are wearing.");
- return(0);
- }
- if(obj == uwep) {
- if(uwep->cursed) {
- pline("Your weapon is welded to your hand!");
- return(0);
- }
- setuwep((struct obj *) 0);
- }
- pline("You dropped %s.", doname(obj));
- dropx(obj);
- return(1);
- }
-
- dropx(obj) register struct obj *obj; {
- if(obj->otyp == CRYSKNIFE)
- obj->otyp = WORM_TOOTH;
- freeinv(obj);
- obj->ox = u.ux;
- obj->oy = u.uy;
- obj->nobj = fobj;
- fobj = obj;
- if(Invis) newsym(u.ux,u.uy);
- subfrombill(obj);
- stackobj(obj);
- }
-
- /* drop several things */
- doddrop() {
- return(ggetobj("drop", drop, 0));
- }
-
- rhack(cmd)
- register char *cmd;
- {
- register struct func_tab *tlist = list;
- boolean firsttime = FALSE;
- register int res;
-
- if(!cmd) {
- firsttime = TRUE;
- flags.nopick = 0;
- cmd = parse();
- }
- if(!*cmd || *cmd == 0377 || (flags.no_rest_on_space && *cmd == ' ')){
- flags.move = 0;
- return; /* probably we just had an interrupt */
- }
- if(movecm(cmd)) {
- walk:
- if(multi) flags.mv = 1;
- domove();
- return;
- }
- if(movecm(lowc(cmd))) {
- flags.run = 1;
- rush:
- if(firsttime){
- if(!multi) multi = COLNO;
- u.last_str_turn = 0;
- }
- flags.mv = 1;
- #ifdef QUEST
- if(flags.run >= 4) finddir();
- if(firsttime){
- u.ux0 = u.ux + u.dx;
- u.uy0 = u.uy + u.dy;
- }
- #endif QUEST
- domove();
- return;
- }
- if((*cmd == 'f' && movecm(cmd+1)) ||
- movecm(unctrl(cmd))) {
- flags.run = 2;
- goto rush;
- }
- if(*cmd == 'F' && movecm(lowc(cmd+1))) {
- flags.run = 3;
- goto rush;
- }
- if(*cmd == 'm' && movecm(cmd+1)) {
- flags.run = 0;
- flags.nopick = 1;
- goto walk;
- }
- if(*cmd == 'M' && movecm(lowc(cmd+1))) {
- flags.run = 1;
- flags.nopick = 1;
- goto rush;
- }
- #ifdef QUEST
- if(*cmd == cmd[1] && (*cmd == 'f' || *cmd == 'F')) {
- flags.run = 4;
- if(*cmd == 'F') flags.run += 2;
- if(cmd[2] == '-') flags.run += 1;
- goto rush;
- }
- #endif QUEST
- while(tlist->f_char) {
- if(*cmd == tlist->f_char){
- res = (*(tlist->f_funct))(0);
- if(!res) {
- flags.move = 0;
- multi = 0;
- }
- return;
- }
- tlist++;
- }
- pline("Unknown command '%s'",cmd);
- multi = flags.move = 0;
- }
-
- doredraw()
- {
- docrt();
- return(0);
- }
-
- dohelp()
- {
- FILE *fp;
- char bufr[BUFSZ];
- int line, i;
-
- if ( (fp = fopen(HELP,"r")) == NULL)
- pline("cannot access help");
- else
- {
- cls();
- line = 1;
- while(fgets(bufr,BUFSZ,fp))
- {
- myprintf("%s", bufr);
- if (line++ > ROWNO)
- {
- myprintf("---more---");
- xwaitforspace(FALSE);
- morc = 0;
- for (i=0;i<10;i++)
- backsp();
- cl_end();
- line = 1;
- }
- }
- more();
- docrt();
- }
- }
-
- #ifdef SHELL
- dosh(){
- char *file, *Open();
- if ( (file = Open("CON:1/1/639/199/Hack SubProcess", 1006)) == NULL)
- pline("cannot create process window");
- if (Execute("", file, NULL))
- pline("cannot execute commands");
- Close(file);
- return(0);
- }
- #endif SHELL
-
- child(wt) {
- pline("Cannot create children");
- docrt();
- return(0);
- }
-
- dodown()
- {
- if(u.ux != xdnstair || u.uy != ydnstair) {
- pline("You can't go down here.");
- return(0);
- }
- if(u.ustuck) {
- pline("You are being held, and cannot go down.");
- return(1);
- }
- if(Levitation) {
- pline("You're floating high above the stairs.");
- return(0);
- }
-
- goto_level(dlevel+1, TRUE);
- return(1);
- }
-
- doup()
- {
- if(u.ux != xupstair || u.uy != yupstair) {
- pline("You can't go up here.");
- return(0);
- }
- if(u.ustuck) {
- pline("You are being held, and cannot go up.");
- return(1);
- }
- if(inv_weight() + 5 > 0) {
- pline("Your load is too heavy to climb the stairs.");
- return(1);
- }
-
- goto_level(dlevel-1, TRUE);
- return(1);
- }
-
- goto_level(newlevel, at_stairs)
- register int newlevel;
- register boolean at_stairs;
- {
- register int fd;
- register boolean up = (newlevel < dlevel);
-
- if(newlevel <= 0) done("escaped"); /* in fact < 0 is impossible */
- if(newlevel == dlevel) return; /* this cannot happen either */
-
- glo(dlevel);
- fd = creat(lock,FMASK);
- if(fd < 0) {
- /*
- * This is not quite impossible: e.g., we may have
- * exceeded our quota. If that is the case then we
- * cannot leave this level, and cannot save either.
- */
- pline("A mysterious force prevents you from going %s.",
- up ? "up" : "down");
- return;
- }
-
- if(Punished) unplacebc();
- keepdogs();
- seeoff(1);
- flags.nscrinh = 1;
- u.ux = FAR; /* hack */
- (void) inshop(); /* probably was a trapdoor */
-
- savelev(fd);
- (void) close(fd);
-
- dlevel = newlevel;
- if(maxdlevel < dlevel)
- maxdlevel = dlevel;
- glo(dlevel);
- if((fd = open(lock,0)) < 0)
- mklev();
- else {
- (void) getlev(fd);
- (void) close(fd);
- }
-
- if(at_stairs) {
- if(up) {
- u.ux = xdnstair;
- u.uy = ydnstair;
- if(!u.ux) { /* entering a maze from below? */
- u.ux = xupstair; /* this will confuse the player! */
- u.uy = yupstair;
- }
- if(Punished){
- pline("With great effort you climb the stairs");
- placebc(1);
- }
- } else {
- u.ux = xupstair;
- u.uy = yupstair;
- if(inv_weight() + 5 > 0 || Punished){
- pline("You fall down the stairs.");
- losehp(rnd(3), "fall");
- if(Punished) {
- if(uwep != uball && rn2(3)){
- pline("... and are hit by the iron ball");
- losehp(rnd(20), "iron ball");
- }
- placebc(1);
- }
- selftouch("Falling, you");
- }
- }
- } else { /* trapdoor or level_tele */
- do {
- u.ux = rnd(COLNO-1);
- u.uy = rn2(ROWNO);
- } while(levl[u.ux][u.uy].typ != ROOM ||
- m_at(u.ux,u.uy));
- if(Punished){
- if(uwep != uball && !up /* %% */ && rn2(5)){
- pline("The iron ball falls on your head.");
- losehp(rnd(25), "iron ball");
- }
- placebc(1);
- }
- selftouch("Falling, you");
- }
- (void) inshop();
- #ifdef TRACK
- initrack();
- #endif TRACK
-
- losedogs();
- flags.nscrinh = 0;
- setsee();
- { register struct monst *mtmp;
- if(mtmp = m_at(u.ux, u.uy)) mnexto(mtmp); /* riv05!a3 */
- }
- docrt();
- pickup();
- read_engr_at(u.ux,u.uy);
- }
-
- donull() {
- return(1); /* Do nothing, but let other things happen */
- }
-
- struct monst *bhit(), *boomhit();
- dothrow()
- {
- register struct obj *obj;
- register struct monst *mon;
- register int tmp;
-
- obj = getobj("#)", "throw"); /* it is also possible to throw food */
- /* (or jewels, or iron balls ... ) */
- if(!obj || !getdir())
- return(0);
- if(obj->owornmask & (W_ARMOR | W_RING)){
- pline("You can't throw something you are wearing");
- return(0);
- }
- if(obj == uwep){
- if(obj->cursed){
- pline("Your weapon is welded to your hand");
- return(1);
- }
- if(obj->quan > 1)
- setuwep(splitobj(obj, 1));
- else
- setuwep((struct obj *) 0);
- }
- else if(obj->quan > 1)
- (void) splitobj(obj, 1);
- freeinv(obj);
- if(u.uswallow) {
- mon = u.ustuck;
- bhitpos.x = mon->mx;
- bhitpos.y = mon->my;
- } else if(obj->otyp == BOOMERANG) {
- mon = boomhit(u.dx,u.dy);
- /* boomhit delivers -1 if the thing was caught */
- if((int) mon == -1) {
- (void) addinv(obj);
- return(1);
- }
- } else
- mon = bhit(u.dx,u.dy,
- (!Punished || obj != uball) ? 8 :
- !u.ustuck ? 5 : 1,
- obj->olet);
- if(mon) {
- /* awake monster if sleeping */
- wakeup(mon);
-
- if(obj->olet == WEAPON_SYM) {
- tmp = -1+u.ulevel+mon->data->ac+abon();
- if(obj->otyp < ROCK) {
- if(!uwep ||
- uwep->otyp != obj->otyp+(BOW-ARROW))
- tmp -= 4;
- else {
- tmp += uwep->spe;
- }
- } else
- if(obj->otyp == BOOMERANG) tmp += 4;
- tmp += obj->spe;
- if(u.uswallow || tmp >= rnd(20)) {
- if(hmon(mon,obj,1) == TRUE){
- /* mon still alive */
- #ifndef NOWORM
- cutworm(mon,bhitpos.x,bhitpos.y,obj->otyp);
- #endif NOWORM
- } else mon = 0;
- /* weapons thrown disappear sometimes */
- if(obj->otyp < BOOMERANG && rn2(3)) {
- /* check bill; free */
- obfree(obj, (struct obj *) 0);
- return(1);
- }
- } else miss(objects[obj->otyp].oc_name, mon);
- } else if(obj->otyp == HEAVY_IRON_BALL) {
- tmp = -1+u.ulevel+mon->data->ac+abon();
- if(!Punished || obj != uball) tmp += 2;
- if(u.utrap) tmp -= 2;
- if(u.uswallow || tmp >= rnd(20)) {
- if(hmon(mon,obj,1) == FALSE)
- mon = 0; /* he died */
- } else miss("iron ball", mon);
- } else {
- if(cansee(bhitpos.x,bhitpos.y))
- pline("You miss %s.",monnam(mon));
- else pline("You miss it.");
- if(obj->olet == FOOD_SYM && mon->data->mlet == 'd')
- if(tamedog(mon,obj)) return(1);
- if(obj->olet == GEM_SYM && mon->data->mlet == 'u'){
- if(obj->dknown && objects[obj->otyp].oc_name_known){
- if(objects[obj->otyp].g_val > 0){
- u.uluck += 5;
- goto valuable;
- } else {
- pline("%s is not interested in your junk.",
- Monnam(mon));
- }
- } else { /* value unknown to @ */
- u.uluck++;
- valuable:
- pline("%s graciously accepts your gift.",
- Monnam(mon));
- mpickobj(mon, obj);
- rloc(mon);
- return(1);
- }
- }
- }
- }
- obj->ox = bhitpos.x;
- obj->oy = bhitpos.y;
- obj->nobj = fobj;
- fobj = obj;
- /* prevent him from throwing articles to the exit and escaping */
- /* subfrombill(obj); */
- stackobj(obj);
- if(Punished && obj == uball &&
- (bhitpos.x != u.ux || bhitpos.y != u.uy)){
- freeobj(uchain);
- unpobj(uchain);
- if(u.utrap){
- if(u.utraptype == TT_PIT)
- pline("The ball pulls you out of the pit!");
- else {
- register long side =
- rn2(3) ? LEFT_SIDE : RIGHT_SIDE;
- pline("The ball pulls you out of the bear trap.");
- pline("Your %s leg is severely damaged.",
- (side == LEFT_SIDE) ? "left" : "right");
- Wounded_legs |= side + rnd(1000);
- losehp(2, "thrown ball");
- }
- u.utrap = 0;
- }
- unsee();
- uchain->nobj = fobj;
- fobj = uchain;
- u.ux = uchain->ox = bhitpos.x - u.dx;
- u.uy = uchain->oy = bhitpos.y - u.dy;
- setsee();
- (void) inshop();
- }
- if(cansee(bhitpos.x, bhitpos.y)) prl(bhitpos.x,bhitpos.y);
- return(1);
- }
-
- /* split obj so that it gets size num */
- /* remainder is put in the object structure delivered by this call */
- struct obj *
- splitobj(obj, num) register struct obj *obj; register int num; {
- register struct obj *otmp;
- otmp = newobj(0);
- *otmp = *obj; /* copies whole structure */
- otmp->o_id = flags.ident++;
- otmp->onamelth = 0;
- obj->quan = num;
- obj->owt = weight(obj);
- otmp->quan -= num;
- otmp->owt = weight(otmp); /* -= obj->owt ? */
- obj->nobj = otmp;
- if(obj->unpaid) splitbill(obj,otmp);
- return(otmp);
- }
-
- char *
- lowc(str)
- register char *str;
- {
- static char buf[2];
-
- if(*str >= 'A' && *str <= 'Z') *buf = *str+'a'-'A';
- else *buf = *str;
- buf[1] = 0;
- return(buf);
- }
-
- char *
- unctrl(str)
- register char *str;
- {
- static char buf[2];
- if(*str >= ('A' & 037) && *str <= ('Z' & 037))
- *buf = *str + 0140;
- else *buf = *str;
- buf[1] = 0;
- return(buf);
- }
-
-