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

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

    1: /*      $NetBSD: hack.engrave.c,v 1.6 2003/04/02 18:36:36 jsm 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.engrave.c,v 1.6 2003/04/02 18:36:36 jsm Exp $");
   67: #endif                          /* not lint */
   68: 
   69: #include <stdlib.h>
   70: #include "hack.h"
   71: #include "extern.h"
   72: 
   73: struct engr {
   74:         struct engr    *nxt_engr;
   75:         char           *engr_txt;
   76:         xchar           engr_x, engr_y;
   77:         unsigned        engr_lth;      /* for save & restore; not length of
   78:                                          * text */
   79:         long            engr_time;     /* moment engraving was (will be)
   80:                                          * finished */
   81:         xchar           engr_type;
   82: #define DUST    1
   83: #define ENGRAVE 2
   84: #define BURN    3
   85: }              *head_engr;
   86: 
   87: struct engr    *
   88: engr_at(x, y)
   89:         xchar           x, y;
   90: {
   91:         struct engr    *ep = head_engr;
   92:         while (ep) {
   93:                 if (x == ep->engr_x && y == ep->engr_y)
   94:                         return (ep);
   95:                 ep = ep->nxt_engr;
   96:         }
   97:         return ((struct engr *) 0);
   98: }
   99: 
  100: int
  101: sengr_at(s, x, y)
  102:         const char     *s;
  103:         xchar           x, y;
  104: {
  105:         struct engr    *ep = engr_at(x, y);
  106:         char           *t;
  107:         int             n;
  108:         if (ep && ep->engr_time <= moves) {
  109:                 t = ep->engr_txt;
  110:                 /*
  111:                                 if(!strcmp(s,t)) return(1);
  112:                 */
  113:                 n = strlen(s);
  114:                 while (*t) {
  115:                         if (!strncmp(s, t, n))
  116:                                 return (1);
  117:                         t++;
  118:                 }
  119:         }
  120:         return (0);
  121: }
  122: 
  123: void
  124: u_wipe_engr(cnt)
  125:         int             cnt;
  126: {
  127:         if (!u.uswallow && !Levitation)
  128:                 wipe_engr_at(u.ux, u.uy, cnt);
  129: }
  130: 
  131: void
  132: wipe_engr_at(x, y, cnt)
  133:         xchar           x, y, cnt;
  134: {
  135:         struct engr    *ep = engr_at(x, y);
  136:         int             lth, pos;
  137:         char            ch;
  138:         if (ep) {
  139:                 if ((ep->engr_type != DUST) || Levitation) {
  140:                         cnt = rn2(1 + 50 / (cnt + 1)) ? 0 : 1;
  141:                 }
  142:                 lth = strlen(ep->engr_txt);
  143:                 if (lth && cnt > 0) {
  144:                         while (cnt--) {
  145:                                 pos = rn2(lth);
  146:                                 if ((ch = ep->engr_txt[pos]) == ' ')
  147:                                         continue;
  148:                                 ep->engr_txt[pos] = (ch != '?') ? '?' : ' ';
  149:                         }
  150:                 }
  151:                 while (lth && ep->engr_txt[lth - 1] == ' ')
  152:                         ep->engr_txt[--lth] = 0;
  153:                 while (ep->engr_txt[0] == ' ')
  154:                         ep->engr_txt++;
  155:                 if (!ep->engr_txt[0])
  156:                         del_engr(ep);
  157:         }
  158: }
  159: 
  160: void
  161: read_engr_at(x, y)
  162:         int             x, y;
  163: {
  164:         struct engr    *ep = engr_at(x, y);
  165:         if (ep && ep->engr_txt[0]) {
  166:                 switch (ep->engr_type) {
  167:                 case DUST:
  168:                         pline("Something is written here in the dust.");
  169:                         break;
  170:                 case ENGRAVE:
  171:                         pline("Something is engraved here on the floor.");
  172:                         break;
  173:                 case BURN:
  174:                         pline("Some text has been burned here in the floor.");
  175:                         break;
  176:                 default:
  177:                         impossible("Something is written in a very strange way.");
  178:                 }
  179:                 pline("You read: \"%s\".", ep->engr_txt);
  180:         }
  181: }
  182: 
  183: void
  184: make_engr_at(x, y, s)
  185:         int             x, y;
  186:         const char     *s;
  187: {
  188:         struct engr    *ep;
  189: 
  190:         if ((ep = engr_at(x, y)) != NULL)
  191:                 del_engr(ep);
  192:         ep = (struct engr *)
  193:                 alloc((unsigned) (sizeof(struct engr) + strlen(s) + 1));
  194:         ep->nxt_engr = head_engr;
  195:         head_engr = ep;
  196:         ep->engr_x = x;
  197:         ep->engr_y = y;
  198:         ep->engr_txt = (char *) (ep + 1);
  199:         (void) strcpy(ep->engr_txt, s);
  200:         ep->engr_time = 0;
  201:         ep->engr_type = DUST;
  202:         ep->engr_lth = strlen(s) + 1;
  203: }
  204: 
  205: int
  206: doengrave()
  207: {
  208:         int             len;
  209:         char           *sp;
  210:         struct engr    *ep, *oep = engr_at(u.ux, u.uy);
  211:         char            buf[BUFSZ];
  212:         xchar           type;
  213:         int             spct;  /* number of leading spaces */
  214:         struct obj     *otmp;
  215:         multi = 0;
  216: 
  217:         if (u.uswallow) {
  218:                 pline("You're joking. Hahaha!");      /* riv05!a3 */
  219:                 return (0);
  220:         }
  221:         /* one may write with finger, weapon or wand */
  222:         otmp = getobj("#-)/", "write with");
  223:         if (!otmp)
  224:                 return (0);
  225: 
  226:         if (otmp == &zeroobj)
  227:                 otmp = 0;
  228:         if (otmp && otmp->otyp == WAN_FIRE && otmp->spe) {
  229:                 type = BURN;
  230:                 otmp->spe--;
  231:         } else {
  232:                 /* first wield otmp */
  233:                 if (otmp != uwep) {
  234:                         if (uwep && uwep->cursed) {
  235:                                 /* Andreas Bormann */
  236:                                 pline("Since your weapon is welded to your hand,");
  237:                                 pline("you use the %s.", aobjnam(uwep, (char *) 0));
  238:                                 otmp = uwep;
  239:                         } else {
  240:                                 if (!otmp)
  241:                                         pline("You are now empty-handed.");
  242:                                 else if (otmp->cursed)
  243:                                         pline("The %s %s to your hand!",
  244:                                               aobjnam(otmp, "weld"),
  245:                                               (otmp->quan == 1) ? "itself" : "themselves");
  246:                                 else
  247:                                         pline("You now wield %s.", doname(otmp));
  248:                                 setuwep(otmp);
  249:                         }
  250:                 }
  251:                 if (!otmp)
  252:                         type = DUST;
  253:                 else if (otmp->otyp == DAGGER || otmp->otyp == TWO_HANDED_SWORD ||
  254:                          otmp->otyp == CRYSKNIFE ||
  255:                          otmp->otyp == LONG_SWORD || otmp->otyp == AXE) {
  256:                         type = ENGRAVE;
  257:                         if ((int) otmp->spe <= -3) {
  258:                                 type = DUST;
  259:                                 pline("Your %s too dull for engraving.",
  260:                                       aobjnam(otmp, "are"));
  261:                                 if (oep && oep->engr_type != DUST)
  262:                                         return (1);
  263:                         }
  264:                 } else
  265:                         type = DUST;
  266:         }
  267:         if (Levitation && type != BURN) {      /* riv05!a3 */
  268:                 pline("You can't reach the floor!");
  269:                 return (1);
  270:         }
  271:         if (oep && oep->engr_type == DUST) {
  272:                 pline("You wipe out the message that was written here.");
  273:                 del_engr(oep);
  274:                 oep = 0;
  275:         }
  276:         if (type == DUST && oep) {
  277:                 pline("You cannot wipe out the message that is %s in the rock.",
  278:                       (oep->engr_type == BURN) ? "burned" : "engraved");
  279:                 return (1);
  280:         }
  281:         pline("What do you want to %s on the floor here? ",
  282:          (type == ENGRAVE) ? "engrave" : (type == BURN) ? "burn" : "write");
  283:         getlin(buf);
  284:         clrlin();
  285:         spct = 0;
  286:         sp = buf;
  287:         while (*sp == ' ')
  288:                 spct++, sp++;
  289:         len = strlen(sp);
  290:         if (!len || *buf == '\033') {
  291:                 if (type == BURN)
  292:                         otmp->spe++;
  293:                 return (0);
  294:         }
  295:         switch (type) {
  296:         case DUST:
  297:         case BURN:
  298:                 if (len > 15) {
  299:                         multi = -(len / 10);
  300:                         nomovemsg = "You finished writing.";
  301:                 }
  302:                 break;
  303:         case ENGRAVE:          /* here otmp != 0 */
  304:                 {
  305:                         int             len2 = (otmp->spe + 3) * 2 + 1;
  306: 
  307:                         pline("Your %s dull.", aobjnam(otmp, "get"));
  308:                         if (len2 < len) {
  309:                                 len = len2;
  310:                                 sp[len] = 0;
  311:                                 otmp->spe = -3;
  312:                                 nomovemsg = "You cannot engrave more.";
  313:                         } else {
  314:                                 otmp->spe -= len / 2;
  315:                                 nomovemsg = "You finished engraving.";
  316:                         }
  317:                         multi = -len;
  318:                 }
  319:                 break;
  320:         }
  321:         if (oep)
  322:                 len += strlen(oep->engr_txt) + spct;
  323:         ep = (struct engr *) alloc((unsigned) (sizeof(struct engr) + len + 1));
  324:         ep->nxt_engr = head_engr;
  325:         head_engr = ep;
  326:         ep->engr_x = u.ux;
  327:         ep->engr_y = u.uy;
  328:         sp = (char *) (ep + 1);        /* (char *)ep + sizeof(struct engr) */
  329:         ep->engr_txt = sp;
  330:         if (oep) {
  331:                 (void) strcpy(sp, oep->engr_txt);
  332:                 (void) strcat(sp, buf);
  333:                 del_engr(oep);
  334:         } else
  335:                 (void) strcpy(sp, buf);
  336:         ep->engr_lth = len + 1;
  337:         ep->engr_type = type;
  338:         ep->engr_time = moves - multi;
  339: 
  340:         /* kludge to protect pline against excessively long texts */
  341:         if (len > BUFSZ - 20)
  342:                 sp[BUFSZ - 20] = 0;
  343: 
  344:         return (1);
  345: }
  346: 
  347: void
  348: save_engravings(fd)
  349:         int             fd;
  350: {
  351:         struct engr    *ep = head_engr;
  352:         while (ep) {
  353:                 if (!ep->engr_lth || !ep->engr_txt[0]) {
  354:                         ep = ep->nxt_engr;
  355:                         continue;
  356:                 }
  357:                 bwrite(fd, (char *) &(ep->engr_lth), sizeof(ep->engr_lth));
  358:                 bwrite(fd, (char *) ep, sizeof(struct engr) + ep->engr_lth);
  359:                 ep = ep->nxt_engr;
  360:         }
  361:         bwrite(fd, (char *) nul, sizeof(unsigned));
  362:         head_engr = 0;
  363: }
  364: 
  365: void
  366: rest_engravings(fd)
  367:         int             fd;
  368: {
  369:         struct engr    *ep;
  370:         unsigned        lth;
  371:         head_engr = 0;
  372:         while (1) {
  373:                 mread(fd, (char *) &lth, sizeof(unsigned));
  374:                 if (lth == 0)
  375:                         return;
  376:                 ep = (struct engr *) alloc(sizeof(struct engr) + lth);
  377:                 mread(fd, (char *) ep, sizeof(struct engr) + lth);
  378:                 ep->nxt_engr = head_engr;
  379:                 ep->engr_txt = (char *) (ep + 1);     /* Andreas Bormann */
  380:                 head_engr = ep;
  381:         }
  382: }
  383: 
  384: void
  385: del_engr(ep)
  386:         struct engr    *ep;
  387: {
  388:         struct engr    *ept;
  389:         if (ep == head_engr)
  390:                 head_engr = ep->nxt_engr;
  391:         else {
  392:                 for (ept = head_engr; ept; ept = ept->nxt_engr) {
  393:                         if (ept->nxt_engr == ep) {
  394:                                 ept->nxt_engr = ep->nxt_engr;
  395:                                 goto fnd;
  396:                         }
  397:                 }
  398:                 impossible("Error in del_engr?");
  399:                 return;
  400: fnd:            ;
  401:         }
  402:         free((char *) ep);
  403: }
Syntax (Markdown)