(linenum→info "unix/slp.c:2238")

bsd-games/2.17/hack/hack.u_init.c

    1: /*      $NetBSD: hack.u_init.c,v 1.8 2004/11/05 21:30:32 dsl Exp $   */
    2: 
    3: /*
    4:  * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
    5:  * Amsterdam
    6:  * All rights reserved.
    7:  *
    8:  * Redistribution and use in source and binary forms, with or without
    9:  * modification, are permitted provided that the following conditions are
   10:  * met:
   11:  *
   12:  * - Redistributions of source code must retain the above copyright notice,
   13:  * this list of conditions and the following disclaimer.
   14:  *
   15:  * - Redistributions in binary form must reproduce the above copyright
   16:  * notice, this list of conditions and the following disclaimer in the
   17:  * documentation and/or other materials provided with the distribution.
   18:  *
   19:  * - Neither the name of the Stichting Centrum voor Wiskunde en
   20:  * Informatica, nor the names of its contributors may be used to endorse or
   21:  * promote products derived from this software without specific prior
   22:  * written permission.
   23:  *
   24:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
   25:  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   26:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
   27:  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   28:  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   29:  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   30:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   31:  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   32:  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   33:  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   34:  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   35:  */
   36: 
   37: /*
   38:  * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
   39:  * All rights reserved.
   40:  *
   41:  * Redistribution and use in source and binary forms, with or without
   42:  * modification, are permitted provided that the following conditions
   43:  * are met:
   44:  * 1. Redistributions of source code must retain the above copyright
   45:  *    notice, this list of conditions and the following disclaimer.
   46:  * 2. Redistributions in binary form must reproduce the above copyright
   47:  *    notice, this list of conditions and the following disclaimer in the
   48:  *    documentation and/or other materials provided with the distribution.
   49:  * 3. The name of the author may not be used to endorse or promote products
   50:  *    derived from this software without specific prior written permission.
   51:  *
   52:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
   53:  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
   54:  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
   55:  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   56:  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   57:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   58:  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   59:  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   60:  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   61:  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   62:  */
   63: 
   64: #include <sys/cdefs.h>
   65: #ifndef lint
   66: __RCSID("$NetBSD: hack.u_init.c,v 1.8 2004/11/05 21:30:32 dsl Exp $");
   67: #endif                          /* not lint */
   68: 
   69: #include <ctype.h>
   70: #include <signal.h>
   71: #include <stdlib.h>
   72: #include "hack.h"
   73: #include "extern.h"
   74: 
   75: #define Strcpy  (void) strcpy
   76: #define Strcat  (void) strcat
   77: #define UNDEF_TYP       0
   78: #define UNDEF_SPE       '\177'
   79: 
   80: struct you      zerou;
   81: char            pl_character[PL_CSIZ];
   82: const char *(roles[]) = {       /* must all have distinct first letter */
   83:         /* roles[4] may be changed to -woman */
   84:         "Tourist", "Speleologist", "Fighter", "Knight",
   85:         "Cave-man", "Wizard"
   86: };
   87: #define NR_OF_ROLES     SIZE(roles)
   88: char            rolesyms[NR_OF_ROLES + 1];      /* filled by u_init() */
   89: 
   90: struct trobj {
   91:         uchar           trotyp;
   92:         schar           trspe;
   93:         char            trolet;
   94:                         Bitfield(trquan, 6);
   95:                         Bitfield(trknown, 1);
   96: };
   97: 
   98: #ifdef WIZARD
   99: struct trobj    Extra_objs[] = {
  100:         {0, 0, 0, 0, 0},
  101:         {0, 0, 0, 0, 0}
  102: };
  103: #endif  /* WIZARD */
  104: 
  105: struct trobj    Cave_man[] = {
  106:         {MACE, 1, WEAPON_SYM, 1, 1},
  107:         {BOW, 1, WEAPON_SYM, 1, 1},
  108:         {ARROW, 0, WEAPON_SYM, 25, 1}, /* quan is variable */
  109:         {LEATHER_ARMOR, 0, ARMOR_SYM, 1, 1},
  110:         {0, 0, 0, 0, 0}
  111: };
  112: 
  113: struct trobj    Fighter[] = {
  114:         {TWO_HANDED_SWORD, 0, WEAPON_SYM, 1, 1},
  115:         {RING_MAIL, 0, ARMOR_SYM, 1, 1},
  116:         {0, 0, 0, 0, 0}
  117: };
  118: 
  119: struct trobj    Knight[] = {
  120:         {LONG_SWORD, 0, WEAPON_SYM, 1, 1},
  121:         {SPEAR, 2, WEAPON_SYM, 1, 1},
  122:         {RING_MAIL, 1, ARMOR_SYM, 1, 1},
  123:         {HELMET, 0, ARMOR_SYM, 1, 1},
  124:         {SHIELD, 0, ARMOR_SYM, 1, 1},
  125:         {PAIR_OF_GLOVES, 0, ARMOR_SYM, 1, 1},
  126:         {0, 0, 0, 0, 0}
  127: };
  128: 
  129: struct trobj    Speleologist[] = {
  130:         {STUDDED_LEATHER_ARMOR, 0, ARMOR_SYM, 1, 1},
  131:         {UNDEF_TYP, 0, POTION_SYM, 2, 0},
  132:         {FOOD_RATION, 0, FOOD_SYM, 3, 1},
  133:         {PICK_AXE, UNDEF_SPE, TOOL_SYM, 1, 0},
  134:         {ICE_BOX, 0, TOOL_SYM, 1, 0},
  135:         {0, 0, 0, 0, 0}
  136: };
  137: 
  138: struct trobj    Tinopener[] = {
  139:         {CAN_OPENER, 0, TOOL_SYM, 1, 1},
  140:         {0, 0, 0, 0, 0}
  141: };
  142: 
  143: struct trobj    Tourist[] = {
  144:         {UNDEF_TYP, 0, FOOD_SYM, 10, 1},
  145:         {POT_EXTRA_HEALING, 0, POTION_SYM, 2, 0},
  146:         {EXPENSIVE_CAMERA, 0, TOOL_SYM, 1, 1},
  147:         {DART, 2, WEAPON_SYM, 25, 1},  /* quan is variable */
  148:         {0, 0, 0, 0, 0}
  149: };
  150: 
  151: struct trobj    Wizard[] = {
  152:         {ELVEN_CLOAK, 0, ARMOR_SYM, 1, 1},
  153:         {UNDEF_TYP, UNDEF_SPE, WAND_SYM, 2, 0},
  154:         {UNDEF_TYP, UNDEF_SPE, RING_SYM, 2, 0},
  155:         {UNDEF_TYP, UNDEF_SPE, POTION_SYM, 2, 0},
  156:         {UNDEF_TYP, UNDEF_SPE, SCROLL_SYM, 3, 0},
  157:         {0, 0, 0, 0, 0}
  158: };
  159: 
  160: void
  161: u_init()
  162: {
  163:         int    i;
  164:         char            exper = 'y', pc;
  165:         if (flags.female)      /* should have been set in HACKOPTIONS */
  166:                 roles[4] = "Cave-woman";
  167:         for (i = 0; i < NR_OF_ROLES; i++)
  168:                 rolesyms[i] = roles[i][0];
  169:         rolesyms[i] = 0;
  170: 
  171:         if ((pc = pl_character[0]) != '\0') {
  172:                 if (islower((unsigned char)pc))
  173:                         pc = toupper((unsigned char)pc);
  174:                 if ((i = role_index(pc)) >= 0)
  175:                         goto got_suffix;     /* implies experienced */
  176:                 printf("\nUnknown role: %c\n", pc);
  177:                 pl_character[0] = pc = 0;
  178:         }
  179:         printf("\nAre you an experienced player? [ny] ");
  180: 
  181:         while (!strchr("ynYN \n\004", (exper = readchar())))
  182:                 bell();
  183:         if (exper == '\004')   /* Give him an opportunity to get out */
  184:                 end_of_input();
  185:         printf("%c\n", exper); /* echo */
  186:         if (strchr("Nn \n", exper)) {
  187:                 exper = 0;
  188:                 goto beginner;
  189:         }
  190:         printf("\nTell me what kind of character you are:\n");
  191:         printf("Are you");
  192:         for (i = 0; i < NR_OF_ROLES; i++) {
  193:                 printf(" a %s", roles[i]);
  194:                 if (i == 2)   /* %% */
  195:                         printf(",\n\t");
  196:                 else if (i < NR_OF_ROLES - 2)
  197:                         printf(",");
  198:                 else if (i == NR_OF_ROLES - 2)
  199:                         printf(" or");
  200:         }
  201:         printf("? [%s] ", rolesyms);
  202: 
  203:         while ((pc = readchar()) != '\0') {
  204:                 if (islower((unsigned char)pc))
  205:                         pc = toupper((unsigned char)pc);
  206:                 if ((i = role_index(pc)) >= 0) {
  207:                         printf("%c\n", pc);  /* echo */
  208:                         (void) fflush(stdout);       /* should be seen */
  209:                         break;
  210:                 }
  211:                 if (pc == '\n')
  212:                         break;
  213:                 if (pc == '\004')     /* Give him the opportunity to get
  214:                                          * out */
  215:                         end_of_input();
  216:                 bell();
  217:         }
  218:         if (pc == '\n')
  219:                 pc = 0;
  220: 
  221: beginner:
  222:         if (!pc) {
  223:                 printf("\nI'll choose a character for you.\n");
  224:                 i = rn2(NR_OF_ROLES);
  225:                 pc = rolesyms[i];
  226:                 printf("This game you will be a%s %s.\n",
  227:                        exper ? "n experienced" : "",
  228:                        roles[i]);
  229:                 getret();
  230:                 /* give him some feedback in case mklev takes much time */
  231:                 (void) putchar('\n');
  232:                 (void) fflush(stdout);
  233:         }
  234: #if 0
  235:         /*
  236:          * Given the above code, I can't see why this would ever change
  237:          * anything; it does core pretty well, though.  - cmh 4/20/93
  238:          */
  239:         if (exper) {
  240:                 roles[i][0] = pc;
  241:         }
  242: #endif
  243: 
  244: got_suffix:
  245: 
  246:         (void) strncpy(pl_character, roles[i], PL_CSIZ - 1);
  247:         pl_character[PL_CSIZ - 1] = 0;
  248:         flags.beginner = 1;
  249:         u = zerou;
  250:         u.usym = '@';
  251:         u.ulevel = 1;
  252:         init_uhunger();
  253: #ifdef QUEST
  254:         u.uhorizon = 6;
  255: #endif  /* QUEST */
  256:         uarm = uarm2 = uarmh = uarms = uarmg = uwep = uball = uchain =
  257:                 uleft = uright = 0;
  258: 
  259:         switch (pc) {
  260:         case 'c':
  261:         case 'C':
  262:                 Cave_man[2].trquan = 12 + rnd(9) * rnd(9);
  263:                 u.uhp = u.uhpmax = 16;
  264:                 u.ustr = u.ustrmax = 18;
  265:                 ini_inv(Cave_man);
  266:                 break;
  267:         case 't':
  268:         case 'T':
  269:                 Tourist[3].trquan = 20 + rnd(20);
  270:                 u.ugold = u.ugold0 = rnd(1000);
  271:                 u.uhp = u.uhpmax = 10;
  272:                 u.ustr = u.ustrmax = 8;
  273:                 ini_inv(Tourist);
  274:                 if (!rn2(25))
  275:                         ini_inv(Tinopener);
  276:                 break;
  277:         case 'w':
  278:         case 'W':
  279:                 for (i = 1; i <= 4; i++)
  280:                         if (!rn2(5))
  281:                                 Wizard[i].trquan += rn2(3) - 1;
  282:                 u.uhp = u.uhpmax = 15;
  283:                 u.ustr = u.ustrmax = 16;
  284:                 ini_inv(Wizard);
  285:                 break;
  286:         case 's':
  287:         case 'S':
  288:                 Fast = INTRINSIC;
  289:                 Stealth = INTRINSIC;
  290:                 u.uhp = u.uhpmax = 12;
  291:                 u.ustr = u.ustrmax = 10;
  292:                 ini_inv(Speleologist);
  293:                 if (!rn2(10))
  294:                         ini_inv(Tinopener);
  295:                 break;
  296:         case 'k':
  297:         case 'K':
  298:                 u.uhp = u.uhpmax = 12;
  299:                 u.ustr = u.ustrmax = 10;
  300:                 ini_inv(Knight);
  301:                 break;
  302:         case 'f':
  303:         case 'F':
  304:                 u.uhp = u.uhpmax = 14;
  305:                 u.ustr = u.ustrmax = 17;
  306:                 ini_inv(Fighter);
  307:                 break;
  308:         default:               /* impossible */
  309:                 u.uhp = u.uhpmax = 12;
  310:                 u.ustr = u.ustrmax = 16;
  311:         }
  312:         find_ac();
  313:         if (!rn2(20)) {
  314:                 int    d = rn2(7) - 2;        /* biased variation */
  315:                 u.ustr += d;
  316:                 u.ustrmax += d;
  317:         }
  318: #ifdef WIZARD
  319:         if (wizard)
  320:                 wiz_inv();
  321: #endif  /* WIZARD */
  322: 
  323:         /* make sure he can carry all he has - especially for T's */
  324:         while (inv_weight() > 0 && u.ustr < 118)
  325:                 u.ustr++, u.ustrmax++;
  326: }
  327: 
  328: void
  329: ini_inv(trop)
  330:         struct trobj *trop;
  331: {
  332:         struct obj *obj;
  333:         while (trop->trolet) {
  334:                 obj = mkobj(trop->trolet);
  335:                 obj->known = trop->trknown;
  336:                 /* not obj->dknown = 1; - let him look at it at least once */
  337:                 obj->cursed = 0;
  338:                 if (obj->olet == WEAPON_SYM) {
  339:                         obj->quan = trop->trquan;
  340:                         trop->trquan = 1;
  341:                 }
  342:                 if (trop->trspe != UNDEF_SPE)
  343:                         obj->spe = trop->trspe;
  344:                 if (trop->trotyp != UNDEF_TYP)
  345:                         obj->otyp = trop->trotyp;
  346:                 else if (obj->otyp == WAN_WISHING)    /* gitpyr!robert */
  347:                         obj->otyp = WAN_DEATH;
  348:                 obj->owt = weight(obj);       /* defined after setting otyp+quan */
  349:                 obj = addinv(obj);
  350:                 if (obj->olet == ARMOR_SYM) {
  351:                         switch (obj->otyp) {
  352:                         case SHIELD:
  353:                                 if (!uarms)
  354:                                         setworn(obj, W_ARMS);
  355:                                 break;
  356:                         case HELMET:
  357:                                 if (!uarmh)
  358:                                         setworn(obj, W_ARMH);
  359:                                 break;
  360:                         case PAIR_OF_GLOVES:
  361:                                 if (!uarmg)
  362:                                         setworn(obj, W_ARMG);
  363:                                 break;
  364:                         case ELVEN_CLOAK:
  365:                                 if (!uarm2)
  366:                                         setworn(obj, W_ARM);
  367:                                 break;
  368:                         default:
  369:                                 if (!uarm)
  370:                                         setworn(obj, W_ARM);
  371:                         }
  372:                 }
  373:                 if (obj->olet == WEAPON_SYM)
  374:                         if (!uwep)
  375:                                 setuwep(obj);
  376: #ifndef PYRAMID_BUG
  377:                 if (--trop->trquan)
  378:                         continue;    /* make a similar object */
  379: #else
  380:                 if (trop->trquan) {   /* check if zero first */
  381:                         --trop->trquan;
  382:                         if (trop->trquan)
  383:                                 continue;   /* make a similar object */
  384:                 }
  385: #endif  /* PYRAMID_BUG */
  386:                 trop++;
  387:         }
  388: }
  389: 
  390: #ifdef WIZARD
  391: void
  392: wiz_inv()
  393: {
  394:         struct trobj *trop = &Extra_objs[0];
  395:         char  *ep = getenv("INVENT");
  396:         int    type;
  397:         while (ep && *ep) {
  398:                 type = atoi(ep);
  399:                 ep = strchr(ep, ',');
  400:                 if (ep)
  401:                         while (*ep == ',' || *ep == ' ')
  402:                                 ep++;
  403:                 if (type <= 0 || type > NROFOBJECTS)
  404:                         continue;
  405:                 trop->trotyp = type;
  406:                 trop->trolet = objects[type].oc_olet;
  407:                 trop->trspe = 4;
  408:                 trop->trknown = 1;
  409:                 trop->trquan = 1;
  410:                 ini_inv(trop);
  411:         }
  412:         /* give him a wand of wishing by default */
  413:         trop->trotyp = WAN_WISHING;
  414:         trop->trolet = WAND_SYM;
  415:         trop->trspe = 20;
  416:         trop->trknown = 1;
  417:         trop->trquan = 1;
  418:         ini_inv(trop);
  419: }
  420: #endif  /* WIZARD */
  421: 
  422: void
  423: plnamesuffix()
  424: {
  425:         char  *p;
  426:         if ((p = strrchr(plname, '-')) != NULL) {
  427:                 *p = 0;
  428:                 pl_character[0] = p[1];
  429:                 pl_character[1] = 0;
  430:                 if (!plname[0]) {
  431:                         askname();
  432:                         plnamesuffix();
  433:                 }
  434:         }
  435: }
  436: 
  437: int
  438: role_index(pc)
  439:         char            pc;
  440: {                               /* must be called only from u_init() */
  441:         /* so that rolesyms[] is defined */
  442:         char  *cp;
  443: 
  444:         if ((cp = strchr(rolesyms, pc)) != NULL)
  445:                 return (cp - rolesyms);
  446:         return (-1);
  447: }
Syntax (Markdown)