|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T o
Length: 12477 (0x30bd) Types: TextFile Names: »outil.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987 └─⟦this⟧ »EUUGD18/General/Omega/outil.c«
/* copyright (c) 1987,1988 by Laurence Raphael Brothers */ /* outils.c */ /* Random utility functions called from all over */ #include "oglob.h" /* x and y on level? */ int inbounds(x,y) int x,y; { return((x>=0)&&(y>=0)&&(x<WIDTH)&&(y<LENGTH)); } /* RANDFUNCTION is defined in odefs.h */ int random_range(k) int k; { return( k==0 ? 0 : (int) RANDFUNCTION % k ) ; } /* modify absolute y coord relative to which part of level we are on */ int screenmod(y) int y; { return(y-ScreenOffset); } int offscreen(y) int y; { return((y<0)|| (y<ScreenOffset) || (y>ScreenOffset+ScreenLength-1) || (y>LENGTH)); } /* always hit on a natural 0; never hit on a natural 19 */ int hitp(hit,ac) int hit,ac; { int roll = random_range(20); if (roll == 0) return(TRUE); else if (roll == 19) return(FALSE); else return((roll < (hit - ac)) ? TRUE : FALSE ); } /* this function doesnt seem to exist by itself... */ int sign(n) int n; { if (n == 0) return(0); else return((n < 0) ? -1 : 1); } /* why load the math library.... */ int max(a,b) int a,b; { return((a>b) ? a : b); } /* why load the math library.... */ int min(a,b) int a,b; { return((a<b) ? a : b); } /* number of moves from x1,y1 to x2,y2 */ int distance(x1,y1,x2,y2) int x1,y1,x2,y2; { return(max(abs(x2-x1),abs(y2-y1))); } /* can you shoot, or move monsters through a spot? */ int unblocked(x,y) int x,y; { if ((! inbounds(x,y)) || (Level->site[x][y].creature != NULL) || (Level->site[x][y].locchar == WALL) || (Level->site[x][y].locchar == PORTCULLIS) || (Level->site[x][y].locchar == STATUE) || (Level->site[x][y].locchar == HEDGE) || (Level->site[x][y].locchar == CLOSED_DOOR) || loc_statusp(x,y,SECRET) || ((x==Player.x) && (y==Player.y))) return(FALSE); else return(TRUE); } /* do monsters want to move through a spot */ int m_unblocked(m,x,y) struct monster *m; int x,y; { if ((! inbounds(x,y)) || ((x==Player.x) && (y==Player.y))) return(FALSE); else if ((Level->site[x][y].creature != NULL) || (Level->site[x][y].locchar == SPACE)) return(FALSE); else if (m_statusp(m,ONLYSWIM)) return(Level->site[x][y].locchar == WATER); else if ((Level->site[x][y].locchar == FLOOR) || (Level->site[x][y].locchar == OPEN_DOOR)) return(TRUE); else if ((Level->site[x][y].locchar == PORTCULLIS) || (Level->site[x][y].locchar == WALL) || (Level->site[x][y].locchar == STATUE) || loc_statusp(x,y,SECRET)) return(m_statusp(m,INTANGIBLE)); else if (Level->site[x][y].locchar==WATER) return(m_statusp(m,SWIMMING) || m_statusp(m,ONLYSWIM) || m_statusp(m,FLYING)); else if (Level->site[x][y].locchar == CLOSED_DOOR) { if (m->movef==M_MOVE_SMART) { mprint("You hear a door creak open."); Level->site[x][y].locchar = OPEN_DOOR; return(TRUE); } else if (random_range(m->dmg) > random_range(100)) { mprint("You hear a door shattering."); Level->site[x][y].locchar = RUBBLE; return(TRUE); } else return(m_statusp(m,INTANGIBLE)); } else if (Level->site[x][y].locchar == LAVA) return((m_immunityp(m,FLAME) && m_statusp(m,SWIMMING)) || m_statusp(m,FLYING)); else if (Level->site[x][y].locchar == FIRE) return(m_immunityp(m,FLAME)); else if ((Level->site[x][y].locchar == TRAP) || (Level->site[x][y].locchar == HEDGE) || (Level->site[x][y].locchar == ABYSS)) return((m->movef == M_MOVE_CONFUSED) || m_statusp(m,FLYING)); else return(TRUE); } /* can you see through a spot? */ int view_unblocked(x,y) int x,y; { if (! inbounds(x,y)) return(FALSE); else if ((Level->site[x][y].locchar == WALL) || (Level->site[x][y].locchar == STATUE) || (Level->site[x][y].locchar == HEDGE) || (Level->site[x][y].locchar == FIRE) || (Level->site[x][y].locchar == CLOSED_DOOR) || loc_statusp(x,y,SECRET)) return(FALSE); else return(TRUE); } /* 8 moves in Dirs */ void initdirs() { Dirs[0][0] = 1; Dirs[0][1] = 1; Dirs[0][2] = -1; Dirs[0][3] = -1; Dirs[0][4] = 1; Dirs[0][5] = -1; Dirs[0][6] = 0; Dirs[0][7] = 0; Dirs[0][8] = 0; Dirs[1][0] = 1; Dirs[1][1] = -1; Dirs[1][2] = 1; Dirs[1][3] = -1; Dirs[1][4] = 0; Dirs[1][5] = 0; Dirs[1][6] = 1; Dirs[1][7] = -1; Dirs[1][8] = 0; } /* do_los moves pyx along a lineofsight from x1 to x2 */ /* x1 and x2 are pointers because as a side effect they are changed */ /* to the final location of the pyx */ void do_los(pyx,x1,y1,x2,y2) char pyx; int *x1,*y1,x2,y2; { int ox,oy,sx,sy,v; do { ox = *x1; oy = *y1; sx=sign(x2-*x1); sy=sign(y2-*y1); if (abs(x2-*x1) > abs(y2-*y1)) *x1 += sx; else if (abs(x2-*x1) < abs(y2-*y1)) *y1 += sy; else { *x1 += sx; *y1 += sy; } Level->site[*x1][*y1].showchar = pyx; /* delay enough to make pyx visible */ for(v=1;v<10;v++) plotchar(pyx,*x1,*y1); plotspot(ox,oy,FALSE); } while(unblocked(*x1,*y1) && ((*x1 != x2) || (*y1 != y2))); plotspot(*x1,*y1,FALSE); levelrefresh(); } /* This is the same as do_los, except we stop before hitting nonliving obstructions */ void do_object_los(pyx,x1,y1,x2,y2) char pyx; int *x1,*y1,x2,y2; { int ox,oy,sx,sy,v; do { ox = *x1; oy = *y1; sx=sign(x2-*x1); sy=sign(y2-*y1); if (abs(x2-*x1) > abs(y2-*y1)) *x1 += sx; else if (abs(x2-*x1) < abs(y2-*y1)) *y1 += sy; else { *x1 += sx; *y1 += sy; } if (unblocked(*x1,*y1)) { for(v=1;v<10;v++) plotchar(pyx,*x1,*y1); Level->site[*x1][*y1].showchar = pyx; } plotspot(ox,oy,TRUE); } while(unblocked(*x1,*y1) && ((*x1 != x2) || (*y1 != y2))); if ((! unblocked(*x1,*y1)) && (Level->site[*x1][*y1].creature == NULL)) { *x1 = ox; *y1 = oy; } plotspot(*x1,*y1,TRUE); levelrefresh(); } /* los_p checks to see whether there is an unblocked los from x1,y1 to x2,y2 */ int los_p(x1,y1,x2,y2) int x1,y1,x2,y2; { int sx,sy; do { sx=sign(x2-x1); sy=sign(y2-y1); if (abs(x2-x1) > abs(y2-y1)) x1 += sx; else if (abs(x2-x1) < abs(y2-y1)) y1 += sy; else { x1 += sx; y1 += sy; } } while (unblocked(x1,y1) && ((x1 != x2) || (y1 != y2))); return((x1==x2) && (y1==y2)); } /* view_los_p sees through monsters */ int view_los_p(x1,y1,x2,y2) int x1,y1,x2,y2; { int sx,sy; do { sx=sign(x2-x1); sy=sign(y2-y1); if (abs(x2-x1) > abs(y2-y1)) x1 += sx; else if (abs(x2-x1) < abs(y2-y1)) y1 += sy; else { x1 += sx; y1 += sy; } } while (view_unblocked(x1,y1) && ((x1 != x2) || (y1 != y2))); return((x1==x2) && (y1==y2)); } int gamestatusp(flag) long flag; { return(GameStatus&flag); } void setgamestatus(flag) long flag; { GameStatus |= flag; } void resetgamestatus(flag) long flag; { GameStatus &= ~flag; } /* returns the command direction from the index into Dirs */ char inversedir(dirindex) int dirindex; { switch (dirindex) { case 0:return('n');break; case 1:return('u');break; case 2:return('b');break; case 3:return('y');break; case 4:return('l');break; case 5:return('h');break; case 6:return('j');break; case 7:return('k');break; } } int calc_points() { int i,points=0; if (gamestatusp(SPOKE_TO_DRUID)) points += 50; if (gamestatusp(COMPLETED_CAVES)) points += 100; if (gamestatusp(COMPLETED_SEWERS)) points += 200; if (gamestatusp(COMPLETED_CASTLE)) points += 300; if (gamestatusp(COMPLETED_ASTRAL)) points += 400; if (gamestatusp(COMPLETED_VOLCANO)) points += 500; if (gamestatusp(KILLED_DRAGONLORD)) points += 100; if (gamestatusp(KILLED_EATER)) points += 100; if (gamestatusp(KILLED_LAWBRINGER)) points += 100; points += Player.xp/50; points += Player.cash/500; for (i=0;i<MAXITEMS;i++) if (Player.possessions[i] != NULL) points += Player.possessions[i]->level*(Player.possessions[i]->known+1); for (i=0;i<MAXPACK;i++) if (Player.pack[i] != NULL) points += Player.pack[i]->level*(Player.pack[i]->known+1); for (i=0;i<NUMRANKS;i++) { if (Player.rank[i] == 5) points += 500; else points += 20*Player.rank[i]; } if (Player.hp < 1) points = (points / 2); else if (Player.rank[ADEPT]) points *= 10; return(points); } /* returns the 24 hour clock hour */ int hour() { return(((Time+720) / 60) % 24); } /* returns 0, 10, 20, 30, 40, or 50 */ int showminute() { return(((Time % 60)/10)*10); } /* returns the 12 hour clock hour */ int showhour() { int showtime; if ((hour() == 0) || (hour() == 12)) showtime = 12; else showtime = (hour() % 12); return(showtime); } /* nighttime is defined from 9 PM to 6AM */ int nighttime() { return((hour() > 20) || (hour() < 7)); } char *getarticle(str) char *str; { if ((str[0]=='a') || (str[0]=='A') || (str[0]=='e') || (str[0]=='E') || (str[0]=='i') || (str[0]=='I') || (str[0]=='o') || (str[0]=='O') || (str[0]=='u') || (str[0]=='U') || (((str[0]=='h') || (str[0]=='H')) && ((str[1]=='i') || (str[1]=='e')))) return("an "); else return("a "); } int day() { return ((Date % 30) + 1); } char *ordinal(number) int number; { if ((number == 11) || (number == 12) || (number == 13)) return("th"); else switch(number % 10) { case 1:return("st");break; case 2:return("nd");break; case 3:return("rd");break; default: return("th");break; } } char *month() { switch((Date % 360) / 30) { case 0: return("Freeze"); break; case 1: return("Ice"); break; case 2: return("Mud"); break; case 3: return("Storm"); break; case 4: return("Breeze"); break; case 5: return("Light"); break; case 6: return("Flame"); break; case 7: return("Broil"); break; case 8: return("Cool"); break; case 9: return("Haunt"); break; case 10: return("Chill"); break; case 11: return("Dark"); break; case 12: return("Twixt"); break; } } /* finds floor space on level with buildaux not equal to baux, sets x,y there. There must *be* floor space somewhere on level.... */ void findspace(x,y,baux) int *x,*y; { int i,j,k,l,done=FALSE; i = k = random_range(WIDTH); j = l = random_range(LENGTH); do { i++; if (i >= WIDTH) { i = 0; j++; if (j > LENGTH) j = 0; done = ((i == k) && (j == l)); } done = done || ((Level->site[i][j].locchar == FLOOR) && (Level->site[i][j].creature == NULL) && (Level->site[i][j].buildaux != baux)); } while (! done); *x = i; *y = j; } /* is prefix a prefix of s? */ int strprefix(prefix,s) char *prefix,*s; { int i=0,matched=TRUE; if (strlen(prefix) > strlen(s)) return(FALSE); else { while (matched && (i<strlen(prefix))) { matched = (prefix[i] == s[i]); i++; } return(matched); } } int confirmation() { switch(random_range(4)) { case 0: mprint("Are you sure? [yn] "); break; case 1: mprint("Certain about that? [yn] "); break; case 2: mprint("Do you really mean it? [yn] "); break; case 3: mprint("Confirm that, would you? [yn] "); break; } return(ynq()=='y'); } /* is character c a member of string s */ int strmem(c,s) char c; char *s; { int i,found=FALSE; for(i=0;((i<strlen(s)) && (! found));i++) found = (s[i] == c); return(found); } /* returns true if its ok to get rid of a level */ int ok_to_free(level) plv level; { if (level == NULL) return(FALSE); else return((level->environment != E_CITY) && (level->environment != E_VILLAGE) && (level->environment != Current_Dungeon)); } void calc_weight() { int i,weight=0; for(i=1;i<MAXITEMS;i++) if (Player.possessions[i] != NULL) weight += Player.possessions[i]->weight * Player.possessions[i]->number; if ((Player.possessions[O_WEAPON_HAND] != NULL) && (Player.possessions[O_READY_HAND] == Player.possessions[O_WEAPON_HAND])) weight -= Player.possessions[O_READY_HAND]->weight * Player.possessions[O_READY_HAND]->number; for(i=1;i<MAXPACK;i++) if (Player.pack[i] != NULL) weight += Player.pack[i]->weight * Player.pack[i]->number; Player.itemweight = weight; dataprint(); } /* alloc just enough string space for str, strcpy, and return pointer */ char *salloc(str) char *str; { char *s=calloc((unsigned)(strlen(str)+1),sizeof(char)); strcpy(s,str); return(s); }