home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / TOP / USR / SRC / larn.t.Z / larn.t / create.c < prev    next >
Text File  |  1988-11-13  |  13KB  |  461 lines

  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.     }
  461.