Annotation of 43BSDReno/games/larn/create.c, revision 1.1.1.1

1.1       root        1: /*     create.c                Larn is copyrighted 1986 by Noah Morgan. */
                      2: #include "header.h"
                      3: extern char spelknow[],larnlevels[];
                      4: extern char beenhere[],wizard,level;
                      5: extern short oldx,oldy;
                      6: /*
                      7:        makeplayer()
                      8: 
                      9:        subroutine to create the player and the players attributes
                     10:        this is called at the beginning of a game and at no other time
                     11:  */
                     12: makeplayer()
                     13:        {
                     14:        register int i;
                     15:        scbr();  clear();
                     16:        c[HPMAX]=c[HP]=10;              /*      start player off with 15 hit points     */
                     17:        c[LEVEL]=1;                             /*      player starts at level one                      */
                     18:        c[SPELLMAX]=c[SPELLS]=1;        /*      total # spells starts off as 3  */
                     19:        c[REGENCOUNTER]=16;             c[ECOUNTER]=96; /*start regeneration correctly*/
                     20:        c[SHIELD] = c[WEAR] = c[WIELD] = -1;
                     21:        for (i=0; i<26; i++)  iven[i]=0;
                     22:        spelknow[0]=spelknow[1]=1; /*he knows protection, magic missile*/
                     23:        if (c[HARDGAME]<=0)
                     24:                {
                     25:                iven[0]=OLEATHER; iven[1]=ODAGGER;
                     26:                ivenarg[1]=ivenarg[0]=c[WEAR]=0;  c[WIELD]=1;
                     27:                }
                     28:        playerx=rnd(MAXX-2);    playery=rnd(MAXY-2);
                     29:        oldx=0;                 oldy=25;
                     30:        gtime=0;                        /*      time clock starts at zero       */
                     31:        cbak[SPELLS] = -50;
                     32:        for (i=0; i<6; i++)  c[i]=12; /* make the attributes, ie str, int, etc. */
                     33:        recalc();
                     34:        }
                     35: 
                     36: /*
                     37:        newcavelevel(level)
                     38:        int level;
                     39: 
                     40:        function to enter a new level.  This routine must be called anytime the
                     41:        player changes levels.  If that level is unknown it will be created.
                     42:        A new set of monsters will be created for a new level, and existing
                     43:        levels will get a few more monsters.
                     44:        Note that it is here we remove genocided monsters from the present level.
                     45:  */
                     46: newcavelevel(x)
                     47:        register int x;
                     48:        {
                     49:        register int i,j;
                     50:        if (beenhere[level]) savelevel();       /* put the level back into storage      */
                     51:        level = x;                              /* get the new level and put in working storage */
                     52:        if (beenhere[x]==0) for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++) know[j][i]=mitem[j][i]=0;
                     53:                else { getlevel(); sethp(0);  goto chgn; }
                     54:        makemaze(x);    makeobject(x);  beenhere[x]=1;  sethp(1);
                     55: 
                     56: #if WIZID
                     57:        if (wizard || x==0)
                     58: #else
                     59:        if (x==0)
                     60: #endif
                     61: 
                     62:                for (j=0; j<MAXY; j++)
                     63:                        for (i=0; i<MAXX; i++)
                     64:                                know[i][j]=1;
                     65: chgn: checkgen();      /* wipe out any genocided monsters */
                     66:        }
                     67: 
                     68: /*
                     69:        makemaze(level)
                     70:        int level;
                     71: 
                     72:        subroutine to make the caverns for a given level.  only walls are made.
                     73:  */
                     74: static int mx,mxl,mxh,my,myl,myh,tmp2;
                     75:  makemaze(k)
                     76:        int k;
                     77:        {
                     78:        register int i,j,tmp;
                     79:        int z;
                     80:        if (k > 1 && (rnd(17)<=4 || k==MAXLEVEL-1 || k==MAXLEVEL+MAXVLEVEL-1))
                     81:                {
                     82:                if (cannedlevel(k));    return;         /* read maze from data file */
                     83:                }
                     84:        if (k==0)  tmp=0;  else tmp=OWALL;
                     85:        for (i=0; i<MAXY; i++)  for (j=0; j<MAXX; j++)  item[j][i]=tmp;
                     86:        if (k==0) return;               eat(1,1);
                     87:        if (k==1) item[33][MAXY-1]=0;   /* exit from dungeon */
                     88: 
                     89: /*     now for open spaces -- not on level 10  */
                     90:        if (k != MAXLEVEL-1)
                     91:                {
                     92:                tmp2 = rnd(3)+3;
                     93:                for (tmp=0; tmp<tmp2; tmp++)
                     94:                        {
                     95:                        my = rnd(11)+2;   myl = my - rnd(2);  myh = my + rnd(2);
                     96:                        if (k < MAXLEVEL)
                     97:                                {
                     98:                                mx = rnd(44)+5;  mxl = mx - rnd(4);  mxh = mx + rnd(12)+3;
                     99:                                z=0;
                    100:                                }
                    101:                        else
                    102:                                {
                    103:                                mx = rnd(60)+3;  mxl = mx - rnd(2);  mxh = mx + rnd(2);
                    104:                                z = makemonst(k);
                    105:                                }
                    106:                        for (i=mxl; i<mxh; i++)         for (j=myl; j<myh; j++)
                    107:                                {  item[i][j]=0;
                    108:                                   if ((mitem[i][j]=z)) hitp[i][j]=monster[z].hitpoints;
                    109:                                }
                    110:                        }
                    111:                }
                    112:        if (k!=MAXLEVEL-1) { my=rnd(MAXY-2);  for (i=1; i<MAXX-1; i++)  item[i][my] = 0; }
                    113:        if (k>1)  treasureroom(k);
                    114:        }
                    115: 
                    116: /*
                    117:        function to eat away a filled in maze
                    118:  */
                    119: eat(xx,yy)
                    120:        register int xx,yy;
                    121:        {
                    122:        register int dir,try;
                    123:        dir = rnd(4);   try=2;
                    124:        while (try)
                    125:                {
                    126:                switch(dir)
                    127:                        {
                    128:                        case 1: if (xx <= 2) break;             /*      west    */
                    129:                                        if ((item[xx-1][yy]!=OWALL) || (item[xx-2][yy]!=OWALL)) break;
                    130:                                        item[xx-1][yy] = item[xx-2][yy] = 0;
                    131:                                        eat(xx-2,yy);   break;
                    132: 
                    133:                        case 2: if (xx >= MAXX-3) break;        /*      east    */
                    134:                                        if ((item[xx+1][yy]!=OWALL) || (item[xx+2][yy]!=OWALL)) break;
                    135:                                        item[xx+1][yy] = item[xx+2][yy] = 0;
                    136:                                        eat(xx+2,yy);   break;
                    137: 
                    138:                        case 3: if (yy <= 2) break;             /*      south   */
                    139:                                        if ((item[xx][yy-1]!=OWALL) || (item[xx][yy-2]!=OWALL)) break;
                    140:                                        item[xx][yy-1] = item[xx][yy-2] = 0;
                    141:                                        eat(xx,yy-2);   break;
                    142: 
                    143:                        case 4: if (yy >= MAXY-3 ) break;       /*      north   */
                    144:                                        if ((item[xx][yy+1]!=OWALL) || (item[xx][yy+2]!=OWALL)) break;
                    145:                                        item[xx][yy+1] = item[xx][yy+2] = 0;
                    146:                                        eat(xx,yy+2);   break;
                    147:                        };
                    148:                if (++dir > 4)  { dir=1;  --try; }
                    149:                }
                    150:        }
                    151: 
                    152: /*
                    153:  *     function to read in a maze from a data file
                    154:  *
                    155:  *     Format of maze data file:  1st character = # of mazes in file (ascii digit)
                    156:  *                             For each maze: 18 lines (1st 17 used) 67 characters per line
                    157:  *
                    158:  *     Special characters in maze data file:
                    159:  *
                    160:  *             #       wall                    D       door                    .       random monster
                    161:  *             ~       eye of larn             !       cure dianthroritis
                    162:  *             -       random object
                    163:  */
                    164: cannedlevel(k)
                    165:        int k;
                    166:        {
                    167:        char *row,*lgetl();
                    168:        register int i,j;
                    169:        int it,arg,mit,marg;
                    170:        if (lopen(larnlevels)<0)
                    171:                {
                    172:                write(1,"Can't open the maze data file\n",30);   died(-282); return(0);
                    173:                }
                    174:        i=lgetc();  if (i<='0') { died(-282); return(0); }
                    175:        for (i=18*rund(i-'0'); i>0; i--)        lgetl();   /* advance to desired maze */
                    176:        for (i=0; i<MAXY; i++)
                    177:                {
                    178:                row = lgetl();
                    179:                for (j=0; j<MAXX; j++)
                    180:                        {
                    181:                        it = mit = arg = marg = 0;
                    182:                        switch(*row++)
                    183:                                {
                    184:                                case '#': it = OWALL;                                                           break;
                    185:                                case 'D': it = OCLOSEDDOOR;     arg = rnd(30);          break;
                    186:                                case '~': if (k!=MAXLEVEL-1) break;
                    187:                                                  it = OLARNEYE;
                    188:                                                  mit = rund(8)+DEMONLORD;
                    189:                                                  marg = monster[mit].hitpoints;                        break;
                    190:                                case '!': if (k!=MAXLEVEL+MAXVLEVEL-1)  break;
                    191:                                                  it = OPOTION;                 arg = 21;
                    192:                                                  mit = DEMONLORD+7;
                    193:                                                  marg = monster[mit].hitpoints;                        break;
                    194:                                case '.': if (k<MAXLEVEL)  break;
                    195:                                                  mit = makemonst(k+1);
                    196:                                                  marg = monster[mit].hitpoints;                        break;
                    197:                                case '-': it = newobject(k+1,&arg);                                     break;
                    198:                                };
                    199:                        item[j][i] = it;                iarg[j][i] = arg;
                    200:                        mitem[j][i] = mit;              hitp[j][i] = marg;
                    201: 
                    202: #if WIZID
                    203:                        know[j][i] = (wizard) ? 1 : 0;
                    204: #else
                    205:                        know[j][i] = 0;
                    206: #endif
                    207:                        }
                    208:                }
                    209:        lrclose();
                    210:        return(1);
                    211:        }
                    212: 
                    213: /*
                    214:        function to make a treasure room on a level
                    215:        level 10's treasure room has the eye in it and demon lords
                    216:        level V3 has potion of cure dianthroritis and demon prince
                    217:  */
                    218: treasureroom(lv)
                    219:        register int lv;
                    220:        {
                    221:        register int tx,ty,xsize,ysize;
                    222: 
                    223:        for (tx=1+rnd(10);  tx<MAXX-10;  tx+=10)
                    224:          if ( (lv==MAXLEVEL-1) || (lv==MAXLEVEL+MAXVLEVEL-1) || rnd(13)==2)
                    225:                {
                    226:                xsize = rnd(6)+3;           ysize = rnd(3)+3;  
                    227:                ty = rnd(MAXY-9)+1;  /* upper left corner of room */
                    228:                if (lv==MAXLEVEL-1 || lv==MAXLEVEL+MAXVLEVEL-1)
                    229:                        troom(lv,xsize,ysize,tx=tx+rnd(MAXX-24),ty,rnd(3)+6);
                    230:                        else troom(lv,xsize,ysize,tx,ty,rnd(9));
                    231:                }
                    232:        }
                    233: 
                    234: /*
                    235:  *     subroutine to create a treasure room of any size at a given location 
                    236:  *     room is filled with objects and monsters 
                    237:  *     the coordinate given is that of the upper left corner of the room
                    238:  */
                    239: troom(lv,xsize,ysize,tx,ty,glyph)
                    240:        int lv,xsize,ysize,tx,ty,glyph;
                    241:        {
                    242:        register int i,j;
                    243:        int tp1,tp2;
                    244:        for (j=ty-1; j<=ty+ysize; j++)
                    245:                for (i=tx-1; i<=tx+xsize; i++)                  /* clear out space for room */
                    246:                        item[i][j]=0;
                    247:        for (j=ty; j<ty+ysize; j++)
                    248:                for (i=tx; i<tx+xsize; i++)                             /* now put in the walls */
                    249:                        {
                    250:                        item[i][j]=OWALL; mitem[i][j]=0; 
                    251:                        }
                    252:        for (j=ty+1; j<ty+ysize-1; j++)
                    253:                for (i=tx+1; i<tx+xsize-1; i++)                 /* now clear out interior */
                    254:                        item[i][j]=0;
                    255: 
                    256:        switch(rnd(2))          /* locate the door on the treasure room */
                    257:                {
                    258:                case 1: item[i=tx+rund(xsize)][j=ty+(ysize-1)*rund(2)]=OCLOSEDDOOR;
                    259:                                iarg[i][j] = glyph;             /* on horizontal walls */
                    260:                                break;
                    261:                case 2: item[i=tx+(xsize-1)*rund(2)][j=ty+rund(ysize)]=OCLOSEDDOOR;
                    262:                                iarg[i][j] = glyph;             /* on vertical walls */
                    263:                                break;
                    264:                };
                    265: 
                    266:        tp1=playerx;  tp2=playery;  playery=ty+(ysize>>1);
                    267:        if (c[HARDGAME]<2)
                    268:                for (playerx=tx+1; playerx<=tx+xsize-2; playerx+=2)
                    269:                        for (i=0, j=rnd(6); i<=j; i++)
                    270:                                { something(lv+2); createmonster(makemonst(lv+1)); }
                    271:        else
                    272:                for (playerx=tx+1; playerx<=tx+xsize-2; playerx+=2)
                    273:                        for (i=0, j=rnd(4); i<=j; i++)
                    274:                                { something(lv+2); createmonster(makemonst(lv+3)); }
                    275: 
                    276:        playerx=tp1;  playery=tp2;
                    277:        }
                    278: 
                    279: /*
                    280:        ***********
                    281:        MAKE_OBJECT
                    282:        ***********
                    283:        subroutine to create the objects in the maze for the given level
                    284:  */
                    285: makeobject(j)
                    286:        register int j;
                    287:        {
                    288:        register int i;
                    289:        if (j==0)
                    290:                {
                    291:                fillroom(OENTRANCE,0);          /*      entrance to dungeon                     */
                    292:                fillroom(ODNDSTORE,0);          /*      the DND STORE                           */
                    293:                fillroom(OSCHOOL,0);            /*      college of Larn                         */
                    294:                fillroom(OBANK,0);                      /*      1st national bank of larn       */
                    295:                fillroom(OVOLDOWN,0);           /*      volcano shaft to temple         */
                    296:                fillroom(OHOME,0);                      /*      the players home & family       */
                    297:                fillroom(OTRADEPOST,0);         /*  the trading post                    */
                    298:                fillroom(OLRS,0);                       /*  the larn revenue service    */
                    299:                return;
                    300:                }
                    301: 
                    302:        if (j==MAXLEVEL) fillroom(OVOLUP,0); /* volcano shaft up from the temple */
                    303: 
                    304: /*     make the fixed objects in the maze STAIRS       */
                    305:        if ((j>0) && (j != MAXLEVEL-1) && (j != MAXLEVEL+MAXVLEVEL-1))
                    306:                fillroom(OSTAIRSDOWN,0);
                    307:        if ((j > 1) && (j != MAXLEVEL))                 fillroom(OSTAIRSUP,0);
                    308: 
                    309: /*     make the random objects in the maze             */
                    310: 
                    311:        fillmroom(rund(3),OBOOK,j);                             fillmroom(rund(3),OALTAR,0);
                    312:        fillmroom(rund(3),OSTATUE,0);                   fillmroom(rund(3),OPIT,0);
                    313:        fillmroom(rund(3),OFOUNTAIN,0);                 fillmroom( rnd(3)-2,OIVTELETRAP,0);
                    314:        fillmroom(rund(2),OTHRONE,0);                   fillmroom(rund(2),OMIRROR,0);
                    315:        fillmroom(rund(2),OTRAPARROWIV,0);              fillmroom( rnd(3)-2,OIVDARTRAP,0);
                    316:        fillmroom(rund(3),OCOOKIE,0);
                    317:        if (j==1) fillmroom(1,OCHEST,j);
                    318:                else fillmroom(rund(2),OCHEST,j);
                    319:        if ((j != MAXLEVEL-1) && (j != MAXLEVEL+MAXVLEVEL-1))
                    320:                fillmroom(rund(2),OIVTRAPDOOR,0);
                    321:        if (j<=10)
                    322:                {
                    323:                fillmroom((rund(2)),ODIAMOND,rnd(10*j+1)+10);
                    324:                fillmroom(rund(2),ORUBY,rnd(6*j+1)+6);
                    325:                fillmroom(rund(2),OEMERALD,rnd(4*j+1)+4);
                    326:                fillmroom(rund(2),OSAPPHIRE,rnd(3*j+1)+2);
                    327:                }
                    328:        for (i=0; i<rnd(4)+3; i++)
                    329:                fillroom(OPOTION,newpotion());  /*      make a POTION   */
                    330:        for (i=0; i<rnd(5)+3; i++)
                    331:                fillroom(OSCROLL,newscroll());  /*      make a SCROLL   */
                    332:        for (i=0; i<rnd(12)+11; i++)
                    333:                fillroom(OGOLDPILE,12*rnd(j+1)+(j<<3)+10); /* make GOLD */
                    334:        if (j==5)       fillroom(OBANK2,0);                             /*      branch office of the bank */
                    335:        froom(2,ORING,0);                               /* a ring mail                  */
                    336:        froom(1,OSTUDLEATHER,0);                /* a studded leather    */
                    337:        froom(3,OSPLINT,0);                             /* a splint mail                */
                    338:        froom(5,OSHIELD,rund(3));               /* a shield                             */
                    339:        froom(2,OBATTLEAXE,rund(3));    /* a battle axe                 */
                    340:        froom(5,OLONGSWORD,rund(3));    /* a long sword                 */
                    341:        froom(5,OFLAIL,rund(3));                /* a flail                              */
                    342:        froom(4,OREGENRING,rund(3));    /* ring of regeneration */
                    343:        froom(1,OPROTRING,rund(3));     /* ring of protection   */
                    344:        froom(2,OSTRRING,4);            /* ring of strength + 4 */
                    345:        froom(7,OSPEAR,rnd(5));         /* a spear                              */
                    346:        froom(3,OORBOFDRAGON,0);        /* orb of dragon slaying*/
                    347:        froom(4,OSPIRITSCARAB,0);               /*scarab of negate spirit*/
                    348:        froom(4,OCUBEofUNDEAD,0);               /* cube of undead control       */
                    349:        froom(2,ORINGOFEXTRA,0);        /* ring of extra regen          */
                    350:        froom(3,ONOTHEFT,0);                    /* device of antitheft          */
                    351:        froom(2,OSWORDofSLASHING,0); /* sword of slashing */
                    352:        if (c[BESSMANN]==0)
                    353:                {
                    354:                froom(4,OHAMMER,0);/*Bessman's flailing hammer*/ c[BESSMANN]=1;
                    355:                }
                    356:        if (c[HARDGAME]<3 || (rnd(4)==3))
                    357:                {
                    358:                if (j>3)
                    359:                        {
                    360:                        froom(3,OSWORD,3);              /* sunsword + 3                 */
                    361:                        froom(5,O2SWORD,rnd(4));  /* a two handed sword */
                    362:                        froom(3,OBELT,4);                       /* belt of striking             */
                    363:                        froom(3,OENERGYRING,3); /* energy ring                  */
                    364:                        froom(4,OPLATE,5);              /* platemail + 5                */
                    365:                        }
                    366:                }
                    367:        }
                    368: 
                    369: /*
                    370:        subroutine to fill in a number of objects of the same kind
                    371:  */
                    372: 
                    373: fillmroom(n,what,arg)
                    374:        int n,arg;
                    375:        char what;
                    376:        {
                    377:        register int i;
                    378:        for (i=0; i<n; i++)             fillroom(what,arg);
                    379:        }
                    380: froom(n,itm,arg)
                    381:        int n,arg;
                    382:        char itm;
                    383:        {       if (rnd(151) < n) fillroom(itm,arg);    }
                    384: 
                    385: /*
                    386:        subroutine to put an object into an empty room
                    387:  *     uses a random walk
                    388:  */
                    389: static fillroom(what,arg)
                    390:        int arg;
                    391:        char what;
                    392:        {
                    393:        register int x,y;
                    394: 
                    395: #ifdef EXTRA
                    396:        c[FILLROOM]++;
                    397: #endif
                    398: 
                    399:        x=rnd(MAXX-2);  y=rnd(MAXY-2);
                    400:        while (item[x][y])
                    401:                {
                    402: 
                    403: #ifdef EXTRA
                    404:                c[RANDOMWALK]++;        /* count up these random walks */
                    405: #endif
                    406: 
                    407:                x += rnd(3)-2;          y += rnd(3)-2;
                    408:                if (x > MAXX-2)  x=1;           if (x < 1)  x=MAXX-2;
                    409:                if (y > MAXY-2)  y=1;           if (y < 1)  y=MAXY-2;
                    410:                }
                    411:        item[x][y]=what;                iarg[x][y]=arg;
                    412:        }
                    413: 
                    414: /*
                    415:        subroutine to put monsters into an empty room without walls or other
                    416:        monsters
                    417:  */
                    418: fillmonst(what)
                    419:        char what;
                    420:        {
                    421:        register int x,y,trys;
                    422:        for (trys=5; trys>0; --trys) /* max # of creation attempts */
                    423:          {
                    424:          x=rnd(MAXX-2);  y=rnd(MAXY-2);
                    425:          if ((item[x][y]==0) && (mitem[x][y]==0) && ((playerx!=x) || (playery!=y)))
                    426:                {
                    427:                mitem[x][y] = what;  know[x][y]=0;
                    428:                hitp[x][y] = monster[what].hitpoints;  return(0);
                    429:                }
                    430:          }
                    431:        return(-1); /* creation failure */
                    432:        }
                    433: 
                    434: /*
                    435:        creates an entire set of monsters for a level
                    436:        must be done when entering a new level
                    437:        if sethp(1) then wipe out old monsters else leave them there
                    438:  */
                    439: sethp(flg)
                    440:        int flg;
                    441:        {
                    442:        register int i,j;
                    443:        if (flg) for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++) stealth[j][i]=0;
                    444:        if (level==0) { c[TELEFLAG]=0; return; } /*     if teleported and found level 1 then know level we are on */
                    445:        if (flg)   j = rnd(12) + 2 + (level>>1);   else   j = (level>>1) + 1;
                    446:        for (i=0; i<j; i++)  fillmonst(makemonst(level));
                    447:        positionplayer();
                    448:        }
                    449: 
                    450: /*
                    451:  *     Function to destroy all genocided monsters on the present level
                    452:  */
                    453: checkgen()
                    454:        {
                    455:        register int x,y;
                    456:        for (y=0; y<MAXY; y++)
                    457:                for (x=0; x<MAXX; x++)
                    458:                        if (monster[mitem[x][y]].genocided)
                    459:                                mitem[x][y]=0; /* no more monster */
                    460:        }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.