|
|
1.1 ! root 1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ ! 2: /* hack.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) || Levitation) { ! 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.