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