home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / HACKSRC.ZIP / ENGRAVE.C < prev    next >
C/C++ Source or Header  |  1985-10-16  |  7KB  |  307 lines

  1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  2. /* engrave.c - version 1.0.3 */
  3.  
  4. #include    "hack.h"
  5.  
  6. extern char *nomovemsg;
  7. extern char nul[];
  8. extern struct obj zeroobj;
  9. struct engr {
  10.     struct engr *nxt_engr;
  11.     char *engr_txt;
  12.     xchar engr_x, engr_y;
  13.     unsigned engr_lth;    /* for save & restore; not length of text */
  14.     long engr_time;    /* moment engraving was (will be) finished */
  15.     xchar engr_type;
  16. #define    DUST    1
  17. #define    ENGRAVE    2
  18. #define    BURN    3
  19. } *head_engr;
  20.  
  21. struct engr *
  22. engr_at(x,y) register xchar x,y; {
  23. register struct engr *ep = head_engr;
  24.     while(ep) {
  25.         if(x == ep->engr_x && y == ep->engr_y)
  26.             return(ep);
  27.         ep = ep->nxt_engr;
  28.     }
  29.     return((struct engr *) 0);
  30. }
  31.  
  32. sengr_at(s,x,y) register char *s; register xchar x,y; {
  33. register struct engr *ep = engr_at(x,y);
  34. register char *t;
  35. register int n;
  36.     if(ep && ep->engr_time <= moves) {
  37.         t = ep->engr_txt;
  38. /*
  39.         if(!strcmp(s,t)) return(1);
  40. */
  41.         n = strlen(s);
  42.         while(*t) {
  43.             if(!strncmp(s,t,n)) return(1);
  44.             t++;
  45.         }
  46.     }
  47.     return(0);
  48. }
  49.  
  50. u_wipe_engr(cnt)
  51. register int cnt;
  52. {
  53.     if(!u.uswallow && !Levitation)
  54.         wipe_engr_at(u.ux, u.uy, cnt);
  55. }
  56.  
  57. wipe_engr_at(x,y,cnt) register xchar x,y,cnt; {
  58. register struct engr *ep = engr_at(x,y);
  59. register int lth,pos;
  60. char ch;
  61.     if(ep){
  62.         if(ep->engr_type != DUST) {
  63.             cnt = rn2(1 + 50/(cnt+1)) ? 0 : 1;
  64.         }
  65.         lth = strlen(ep->engr_txt);
  66.         if(lth && cnt > 0 ) {
  67.             while(cnt--) {
  68.                 pos = rn2(lth);
  69.                 if((ch = ep->engr_txt[pos]) == ' ')
  70.                     continue;
  71.                 ep->engr_txt[pos] = (ch != '?') ? '?' : ' ';
  72.             }
  73.         }
  74.         while(lth && ep->engr_txt[lth-1] == ' ')
  75.             ep->engr_txt[--lth] = 0;
  76.         while(ep->engr_txt[0] == ' ')
  77.             ep->engr_txt++;
  78.         if(!ep->engr_txt[0]) del_engr(ep);
  79.     }
  80. }
  81.  
  82. read_engr_at(x,y) register int x,y; {
  83. register struct engr *ep = engr_at(x,y);
  84.     if(ep && ep->engr_txt[0]) {
  85.         switch(ep->engr_type) {
  86.         case DUST:
  87.         pline("Something is written here in the dust.");
  88.         break;
  89.         case ENGRAVE:
  90.         pline("Something is engraved here on the floor.");
  91.         break;
  92.         case BURN:
  93.         pline("Some text has been burned here in the floor.");
  94.         break;
  95.         default:
  96.         impossible("Something is written in a very strange way.");
  97.         }
  98.         pline("You read: \"%s\".", ep->engr_txt);
  99.     }
  100. }
  101.  
  102. make_engr_at(x,y,s)
  103. register int x,y;
  104. register char *s;
  105. {
  106.     register struct engr *ep;
  107.  
  108.     if(ep = engr_at(x,y))
  109.         del_engr(ep);
  110.     ep = (struct engr *)
  111.         alloc((unsigned)(sizeof(struct engr) + strlen(s) + 1));
  112.     ep->nxt_engr = head_engr;
  113.     head_engr = ep;
  114.     ep->engr_x = x;
  115.     ep->engr_y = y;
  116.     ep->engr_txt = (char *)(ep + 1);
  117.     (void) strcpy(ep->engr_txt, s);
  118.     ep->engr_time = 0;
  119.     ep->engr_type = DUST;
  120.     ep->engr_lth = strlen(s) + 1;
  121. }
  122.  
  123. doengrave(){
  124. register int len;
  125. register char *sp;
  126. register struct engr *ep, *oep = engr_at(u.ux,u.uy);
  127. char buf[BUFSZ];
  128. xchar type;
  129. int spct;        /* number of leading spaces */
  130. register struct obj *otmp;
  131.     multi = 0;
  132.  
  133.     if(u.uswallow) {
  134.         pline("You're joking. Hahaha!");    /* riv05!a3 */
  135.         return(0);
  136.     }
  137.  
  138.     /* one may write with finger, weapon or wand */
  139.     otmp = getobj("#-)/", "write with");
  140.     if(!otmp) return(0);
  141.  
  142.     if(otmp == &zeroobj)
  143.         otmp = 0;
  144.      if(otmp && otmp->otyp == WAN_FIRE && otmp->spe) {
  145.         type = BURN;
  146.         otmp->spe--;
  147.     } else {
  148.         /* first wield otmp */
  149.         if(otmp != uwep) {
  150.             if(uwep && uwep->cursed) {
  151.                 /* Andreas Bormann */
  152.                 pline("Since your weapon is welded to your hand,");
  153.                 pline("you use the %s.", aobjnam(uwep, (char *) 0));
  154.                 otmp = uwep;
  155.             } else {
  156.                 if(!otmp)
  157.                 pline("You are now empty-handed.");
  158.                 else if(otmp->cursed)
  159.                 pline("The %s %s to your hand!",
  160.                     aobjnam(otmp, "weld"),
  161.                     (otmp->quan == 1) ? "itself" : "themselves");
  162.                 else
  163.                 pline("You now wield %s.", doname(otmp));
  164.                 setuwep(otmp);
  165.             }
  166.         }
  167.  
  168.         if(!otmp)
  169.             type = DUST;
  170.         else
  171.         if(otmp->otyp == DAGGER || otmp->otyp == TWO_HANDED_SWORD ||
  172.         otmp->otyp == CRYSKNIFE ||
  173.         otmp->otyp == LONG_SWORD || otmp->otyp == AXE) {
  174.             type = ENGRAVE;
  175.             if((int)otmp->spe <= -3) {
  176.                 type = DUST;
  177.                 pline("Your %s too dull for engraving.",
  178.                     aobjnam(otmp, "are"));
  179.                 if(oep && oep->engr_type != DUST) return(1);
  180.             }
  181.         } else    type = DUST;
  182.     }
  183.     if(Levitation && type != BURN){        /* riv05!a3 */
  184.         pline("You can't reach the floor!");
  185.         return(1);
  186.     }
  187.     if(oep && oep->engr_type == DUST){
  188.           pline("You wipe out the message that was written here.");
  189.           del_engr(oep);
  190.           oep = 0;
  191.     }
  192.     if(type == DUST && oep){
  193.     pline("You cannot wipe out the message that is %s in the rock.",
  194.             (oep->engr_type == BURN) ? "burned" : "engraved");
  195.           return(1);
  196.     }
  197.  
  198.     pline("What do you want to %s on the floor here? ",
  199.       (type == ENGRAVE) ? "engrave" : (type == BURN) ? "burn" : "write");
  200.     getlin(buf);
  201.     clrlin();
  202.     spct = 0;
  203.     sp = buf;
  204.     while(*sp == ' ') spct++, sp++;
  205.     len = strlen(sp);
  206.     if(!len || *buf == '\033') {
  207.         if(type == BURN) otmp->spe++;
  208.         return(0);
  209.     }
  210.     
  211.     switch(type) {
  212.     case DUST:
  213.     case BURN:
  214.         if(len > 15) {
  215.             multi = -(len/10);
  216.             nomovemsg = "You finished writing.";
  217.         }
  218.         break;
  219.     case ENGRAVE:        /* here otmp != 0 */
  220.         {    int len2 = (otmp->spe + 3) * 2 + 1;
  221.  
  222.             pline("Your %s dull.", aobjnam(otmp, "get"));
  223.             if(len2 < len) {
  224.                 len = len2;
  225.                 sp[len] = 0;
  226.                 otmp->spe = -3;
  227.                 nomovemsg = "You cannot engrave more.";
  228.             } else {
  229.                 otmp->spe -= len/2;
  230.                 nomovemsg = "You finished engraving.";
  231.             }
  232.             multi = -len;
  233.         }
  234.         break;
  235.     }
  236.     if(oep) len += strlen(oep->engr_txt) + spct;
  237.     ep = (struct engr *) alloc((unsigned)(sizeof(struct engr) + len + 1));
  238.     ep->nxt_engr = head_engr;
  239.     head_engr = ep;
  240.     ep->engr_x = u.ux;
  241.     ep->engr_y = u.uy;
  242.     sp = (char *)(ep + 1);    /* (char *)ep + sizeof(struct engr) */
  243.     ep->engr_txt = sp;
  244.     if(oep) {
  245.         (void) strcpy(sp, oep->engr_txt);
  246.         (void) strcat(sp, buf);
  247.         del_engr(oep);
  248.     } else
  249.         (void) strcpy(sp, buf);
  250.     ep->engr_lth = len+1;
  251.     ep->engr_type = type;
  252.     ep->engr_time = moves-multi;
  253.  
  254.     /* kludge to protect pline against excessively long texts */
  255.     if(len > BUFSZ-20) sp[BUFSZ-20] = 0;
  256.  
  257.     return(1);
  258. }
  259.  
  260. save_engravings(fd) int fd; {
  261. register struct engr *ep = head_engr;
  262.     while(ep) {
  263.         if(!ep->engr_lth || !ep->engr_txt[0]){
  264.             ep = ep->nxt_engr;
  265.             continue;
  266.         }
  267.         bwrite(fd, (char *) & (ep->engr_lth), sizeof(ep->engr_lth));
  268.         bwrite(fd, (char *) ep, sizeof(struct engr) + ep->engr_lth);
  269.         ep = ep->nxt_engr;
  270.     }
  271.     bwrite(fd, (char *) nul, sizeof(unsigned));
  272.     head_engr = 0;
  273. }
  274.  
  275. rest_engravings(fd) int fd; {
  276. register struct engr *ep;
  277. unsigned lth;
  278.     head_engr = 0;
  279.     while(1) {
  280.         mread(fd, (char *) <h, sizeof(unsigned));
  281.         if(lth == 0) return;
  282.         ep = (struct engr *) alloc(sizeof(struct engr) + lth);
  283.         mread(fd, (char *) ep, sizeof(struct engr) + lth);
  284.         ep->nxt_engr = head_engr;
  285.         ep->engr_txt = (char *) (ep + 1);    /* Andreas Bormann */
  286.         head_engr = ep;
  287.     }
  288. }
  289.  
  290. del_engr(ep) register struct engr *ep; {
  291. register struct engr *ept;
  292.     if(ep == head_engr)
  293.         head_engr = ep->nxt_engr;
  294.     else {
  295.         for(ept = head_engr; ept; ept = ept->nxt_engr) {
  296.             if(ept->nxt_engr == ep) {
  297.                 ept->nxt_engr = ep->nxt_engr;
  298.                 goto fnd;
  299.             }
  300.         }
  301.         impossible("Error in del_engr?");
  302.         return;
  303.     fnd:    ;
  304.     }
  305.     free((char *) ep);
  306. }
  307.