Annotation of 43BSDReno/games/larn/create.c, revision 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.