void free_kill_entries(void) { register group_header *gh; register kill_group_regexp *tb; register int n; Loop_Groups_Header(gh) if (gh->kill_list) { free_kill_list((kill_list_entry *) (gh->kill_list)); gh->kill_list = NULL; } free_kill_list(global_kill_list); global_kill_list = NULL; if ((tb = group_regexp_table)) { for (n = regexp_table_size; --n >= 0; tb++) if (tb->group_regexp != NULL) freeobj(tb->group_regexp); freeobj(group_regexp_table); group_regexp_table = NULL; } if (kill_patterns != NULL) freeobj(kill_patterns); if (kill_tab != NULL) freeobj(kill_tab); kill_file_loaded = 0; }
static void free_kill_list(register kill_list_entry * kl) { register kill_list_entry *nxt; while (kl) { nxt = kl->next_kill; if (kl->kill_regexp != NULL) freeobj(kl->kill_regexp); if ((kl->kill_flag & COMP_KILL_ENTRY) == 0) { if (kl->kill_pattern != NULL) freeobj(kl->kill_pattern); freeobj(kl); } kl = nxt; } }
void region_renew_ (RStack *rs, Region *creg, RObject *base, RObject *top) { creg->top = base; lua_assert(0 < rs->cregnum && rs->cregnum < RStack_REGIONS); do { GCObject *o = (--top)->body; if (o) freeobj(rs->state, o); } while (top != base); lua_assert(rs->creg->top == base); }
/** * Delete the font. */ Font::~Font () { int count; //for (count = 0; count < nCharacters; count++) SDL_FreeSurface(characters[count]); if(ramid!=INVALID_OBJ) freeobj(ramid); return; }
void region_free (RStack *rs) { Region *creg = rs->creg; RObject *top = creg->top; RObject *base = creg->base; lua_assert(0 < rs->cregnum && rs->cregnum < RStack_REGIONS); --rs->cregnum; --rs->creg; while (top != base) { GCObject *o = (--top)->body; if (o) freeobj(rs->state, o); } lua_assert(rs->creg->top == base); }
static int sweeplist (lua_State *L, GCObject **p, int limit) { GCObject *curr; int count = 0; /* number of collected items */ while ((curr = *p) != NULL) { if (curr->gch.marked > limit) { unmark(curr); p = &curr->gch.next; } else { count++; *p = curr->gch.next; freeobj(L, curr); } } return count; }
int wiz_hit(struct monst *mtmp) { /* if we have stolen or found the amulet, we disappear */ if(mtmp->minvent && mtmp->minvent->olet == AMULET_SYM && mtmp->minvent->spe == 0) { /* vanish -- very primitive */ fall_down(mtmp); return(1); } /* if it is lying around someplace, we teleport to it */ if(!carrying(AMULET_OF_YENDOR)) { struct obj *otmp; for(otmp = fobj; otmp; otmp = otmp->nobj) if(otmp->olet == AMULET_SYM && !otmp->spe) { if((u.ux != otmp->ox || u.uy != otmp->oy) && !m_at(otmp->ox, otmp->oy)) { /* teleport to it and pick it up */ mtmp->mx = otmp->ox; mtmp->my = otmp->oy; freeobj(otmp); mpickobj(mtmp, otmp); pmon(mtmp); return(0); } goto hithim; } return(0); /* we don't know where it is */ } hithim: if(rn2(2)) { /* hit - perhaps steal */ /* if hit 1/20 chance of stealing amulet & vanish - amulet is on level 26 again. */ if(hitu(mtmp, d(mtmp->data->damn,mtmp->data->damd)) && !rn2(20) && stealamulet(mtmp)) ; } else inrange(mtmp); /* try magic */ return(0); }
static int sweeplist (lua_State *L, GCObject **p, GCObject *tail, int limit) { #if 0 GCObject **start = p; #endif 0 GCObject *curr; int count = 0; /* number of collected items */ while ((curr = *p) != tail) { if (curr->gch.marked > limit) { unmark(curr); p = &curr->gch.next; } else { count++; *p = curr->gch.next; #if LUA_REFCOUNT if (curr->gch.prev) { Unlink(curr); curr->gch.next->gch.prev = (GCObject*)p; } #endif LUA_REFCOUNT freeobj(L, curr); } } #if 0 while (1) { curr = *p; if (curr == NULL) break; if (curr->gch.next) lua_assert(!curr->gch.next->gch.prev || curr->gch.next->gch.prev == curr); if (curr->gch.prev) lua_assert(curr->gch.prev->gch.next == curr); start = &curr->gch.next; } #endif 0 return count; }
void mpickgems(struct monst *mtmp) { struct obj *otmp; for(otmp = fobj; otmp != NULL; otmp = otmp->nobj) { if(otmp->olet == GEM_SYM) { if((otmp->ox == mtmp->mx) && (otmp->oy == mtmp->my)) { if((mtmp->data->mlet != 'u') || (objects[otmp->otyp].g_val != 0)) { freeobj(otmp); mpickobj(mtmp, otmp); if(levl[(int)mtmp->mx][(int)mtmp->my].scrsym == GEM_SYM) { /* %% */ newsym(mtmp->mx, mtmp->my); } /* Pick only one object */ return; } } } } }
void cleanup() { lexer_free(); freeobj(literalTable); vm_free(); }
int doeat(void) { struct obj *otmp; int tmp; // Is there some food (probably a heavy corpse) here on the ground? if (!Levitation) for (otmp = _level->objects; otmp; otmp = otmp->nobj) { if (otmp->ox == _u.ux && otmp->oy == _u.uy && otmp->olet == FOOD_SYM) { pline("There %s %s here; eat %s? [ny] ", (otmp->quan == 1) ? "is" : "are", doname(otmp), (otmp->quan == 1) ? "it" : "one"); if (readchar() == 'y') { if (otmp->quan != 1) (void) splitobj(otmp, 1); freeobj(otmp); otmp = addinv(otmp); addtobill(otmp); goto gotit; } } } otmp = getobj("%", "eat"); if (!otmp) return 0; gotit: if (otmp->otyp == TIN) { if (uwep) { switch (uwep->otyp) { case CAN_OPENER: tmp = 1; break; case DAGGER: tmp = 3; break; case PICK_AXE: case AXE: tmp = 6; break; default: goto no_opener; } pline("Using your %s you try to open the tin.", aobjnam(uwep, NULL)); } else { no_opener: pline("It is not so easy to open this tin."); if (Glib) { pline("The tin slips out of your hands."); if (otmp->quan > 1) { struct obj *obj; obj = splitobj(otmp, 1); if (otmp == uwep) setuwep(obj); } dropx(otmp); return 1; } tmp = 10 + rn2(1 + 500 / ((int) (_u.ulevel + _u.ustr))); } tin.reqtime = tmp; tin.usedtime = 0; tin.tin = otmp; occupation = opentin; occtxt = "opening the tin"; return 1; } const struct objclass* ftmp = &c_Objects[otmp->otyp]; multi = -ftmp->oc_delay; if (otmp->otyp >= CORPSE && eatcorpse(otmp)) goto eatx; if (!rn2(7) && otmp->otyp != FORTUNE_COOKIE) { pline("Blecch! Rotten food!"); if (!rn2(4)) { pline("You feel rather light headed."); Confusion += d(2, 4); } else if (!rn2(4) && !Blind) { pline("Everything suddenly goes dark."); Blind = d(2, 10); seeoff(0); } else if (!rn2(3)) { if (Blind) pline("The world spins and you slap against the floor."); else pline("The world spins and goes dark."); nomul(-rnd(10)); nomovemsg = "You are conscious again."; } lesshungry(ftmp->nutrition / 4); } else { if (_u.uhunger >= 1500) { pline("You choke over your food."); pline("You die..."); killer = ftmp->oc_name; done("choked"); } switch (otmp->otyp) { case FOOD_RATION: if (_u.uhunger <= 200) pline("That food really hit the spot!"); else if (_u.uhunger <= 700) pline("That satiated your stomach!"); else { pline("You're having a hard time getting all that food down."); multi -= 2; } lesshungry(ftmp->nutrition); if (multi < 0) nomovemsg = "You finished your meal."; break; case TRIPE_RATION: pline("Yak - dog food!"); more_experienced(1, 0); _wflags.botl = 1; if (rn2(2)) { pline("You vomit."); morehungry(20); if (Sick) { Sick = 0; // David Neves pline("What a relief!"); } } else lesshungry(ftmp->nutrition); break; default: if (otmp->otyp >= CORPSE) pline("That %s tasted terrible!", ftmp->oc_name); else pline("That %s was delicious!", ftmp->oc_name); lesshungry(ftmp->nutrition); if (otmp->otyp == DEAD_LIZARD && (Confusion > 2)) Confusion = 2; else if (otmp->otyp == FORTUNE_COOKIE) { if (Blind) { pline("This cookie has a scrap of paper inside!"); pline("What a pity, that you cannot read it!"); } else print_rumor(); } else if (otmp->otyp == LUMP_OF_ROYAL_JELLY) { // This stuff seems to be VERY healthy! if (_u.ustrmax < 118) ++_u.ustrmax; if (_u.ustr < _u.ustrmax) ++_u.ustr; _u.uhp += rnd(20); if (_u.uhp > _u.uhpmax) { if (!rn2(17)) ++_u.uhpmax; _u.uhp = _u.uhpmax; } heal_legs(); } break; } } eatx: if (multi < 0 && !nomovemsg) { static char msgbuf[BUFSZ]; sprintf(msgbuf, "You finished eating the %s.", ftmp->oc_name); nomovemsg = msgbuf; } useup(otmp); return 1; }
static void cleartable (lua_State *L, GCObject *l) { #else static void cleartable (GCObject *l) { #endif /* LUA_REFCOUNT */ while (l) { Table *h = gco2h(l); int i = h->sizearray; lua_assert(testbit(h->marked, VALUEWEAKBIT) || testbit(h->marked, KEYWEAKBIT)); if (testbit(h->marked, VALUEWEAKBIT)) { while (i--) { TValue *o = &h->array[i]; #if LUA_REFCOUNT if (iscleared(o, 0)) { /* value was collected? */ if (iscollectable(o)) o->value.gc->gch.ref--; setnilvalue2n(l, o); /* remove value */ } #else if (iscleared(o, 0)) /* value was collected? */ setnilvalue(o); /* remove value */ #endif /* LUA_REFCOUNT */ } } i = sizenode(h); while (i--) { Node *n = gnode(h, i); if (!ttisnil(gval(n)) && /* non-empty entry? */ (iscleared(key2tval(n), 1) || iscleared(gval(n), 0))) { #if LUA_REFCOUNT if (iscollectable(gval(n))) gval(n)->value.gc->gch.ref--; setnilvalue2n(L, gval(n)); /* remove value ... */ #else setnilvalue(gval(n)); /* remove value ... */ #endif /* LUA_REFCOUNT */ removeentry(n); /* remove entry from table */ } } l = h->gclist; } } static void freeobj (lua_State *L, GCObject *o) { switch (o->gch.tt) { case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break; case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break; case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break; case LUA_TTABLE: luaH_free(L, gco2h(o)); break; case LUA_TTHREAD: { lua_assert(gco2th(o) != L && gco2th(o) != G(L)->mainthread); luaE_freethread(L, gco2th(o)); break; } case LUA_TSTRING: { G(L)->strt.nuse--; luaM_freemem(L, o, sizestring(gco2ts(o))); break; } #if LUA_WIDESTRING case LUA_TWSTRING: { G(L)->strt.nuse--; luaM_freemem(L, o, sizestring(gco2ts(o))); break; } #endif /* LUA_WIDESTRING */ case LUA_TUSERDATA: { luaM_freemem(L, o, sizeudata(gco2u(o))); break; } default: lua_assert(0); } } #define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM) static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { GCObject *curr; global_State *g = G(L); int deadmask = otherwhite(g); while ((curr = *p) != NULL && count-- > 0) { if (curr->gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */ sweepwholelist(L, &gco2th(curr)->openupval); if ((curr->gch.marked ^ WHITEBITS) & deadmask) { /* not dead? */ lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT)); makewhite(g, curr); /* make it white (for next cycle) */ p = &curr->gch.next; } else { /* must erase `curr' */ lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT)); #if LUA_REFCOUNT if (curr->gch.prev) curr->gch.prev->gch.next = curr->gch.next; if (curr->gch.next) curr->gch.next->gch.prev = (GCObject*)p; #endif /* LUA_REFCOUNT */ *p = curr->gch.next; if (curr == g->rootgc) /* is the first element of the list? */ g->rootgc = curr->gch.next; /* adjust first */ freeobj(L, curr); } } return p; }
/* return 0 (no move), 1 (move) or 2 (dead) */ int dog_move(struct monst *mtmp, int after) { int nx, ny, omx, omy, appr, nearer, j; int udist, chi, i, whappr; struct monst *mtmp2; struct permonst *mdat = mtmp->data; struct edog *edog = EDOG(mtmp); struct obj *obj; struct trap *trap; xchar cnt, chcnt, nix, niy; schar dogroom, uroom; xchar gx, gy, gtyp, otyp; /* current goal */ coord poss[9]; int info[9]; #define GDIST(x,y) ((x-gx)*(x-gx) + (y-gy)*(y-gy)) #define DDIST(x,y) ((x-omx)*(x-omx) + (y-omy)*(y-omy)) if(moves <= edog->eattime) return(0); /* dog is still eating */ omx = mtmp->mx; omy = mtmp->my; whappr = (moves - EDOG(mtmp)->whistletime < 5); if(moves > edog->hungrytime + 500 && !mtmp->mconf){ mtmp->mconf = 1; mtmp->mhpmax /= 3; if(mtmp->mhp > mtmp->mhpmax) mtmp->mhp = mtmp->mhpmax; if(cansee(omx,omy)) pline("%s is confused from hunger.", Monnam(mtmp)); else pline("You feel worried about %s.", monnam(mtmp)); } else if(moves > edog->hungrytime + 750 || mtmp->mhp < 1){ if(cansee(omx,omy)) pline("%s dies from hunger.", Monnam(mtmp)); else pline("You have a sad feeling for a moment, then it passes."); mondied(mtmp); return(2); } dogroom = inroom(omx,omy); uroom = inroom(u.ux,u.uy); udist = dist(omx,omy); /* maybe we tamed him while being swallowed --jgm */ if(!udist) return(0); /* if we are carrying sth then we drop it (perhaps near @) */ /* Note: if apport == 1 then our behaviour is independent of udist */ if(mtmp->minvent){ if(!rn2(udist) || !rn2((int) edog->apport)) if(rn2(10) < edog->apport){ relobj(mtmp, (int) mtmp->minvis); if(edog->apport > 1) edog->apport--; edog->dropdist = udist; /* hpscdi!jon */ edog->droptime = moves; } } else { if ((obj = o_at(omx,omy))) if(!strchr("0_", obj->olet)){ if((otyp = dogfood(obj)) <= CADAVER){ nix = omx; niy = omy; goto eatobj; } if (obj->owt < 10*mtmp->data->mlevel) if (rn2(20) < edog->apport+3) if (rn2(udist) || !rn2((int) edog->apport)){ freeobj(obj); unpobj(obj); /* if(levl[omx][omy].scrsym == obj->olet) newsym(omx,omy); */ mpickobj(mtmp,obj); } } } /* first we look for food */ gtyp = UNDEF; /* no goal as yet */ gx = gy = 0; for(obj = fobj; obj; obj = obj->nobj) { otyp = dogfood(obj); if(otyp > gtyp || otyp == UNDEF) continue; if(inroom(obj->ox,obj->oy) != dogroom) continue; if(otyp < MANFOOD && (dogroom >= 0 || DDIST(obj->ox,obj->oy) < 10)) { if(otyp < gtyp || (otyp == gtyp && DDIST(obj->ox,obj->oy) < DDIST(gx,gy))){ gx = obj->ox; gy = obj->oy; gtyp = otyp; } } else if(gtyp == UNDEF && dogroom >= 0 && uroom == dogroom && !mtmp->minvent && edog->apport > rn2(8)){ gx = obj->ox; gy = obj->oy; gtyp = APPORT; } } if(gtyp == UNDEF || (gtyp != DOGFOOD && gtyp != APPORT && moves < edog->hungrytime)){ if(dogroom < 0 || dogroom == uroom){ gx = u.ux; gy = u.uy; #ifndef QUEST } else { int tmp = rooms[(int)dogroom].fdoor; cnt = rooms[(int)dogroom].doorct; gx = gy = FAR; /* random, far away */ while(cnt--){ if(dist(gx,gy) > dist(doors[tmp].x, doors[tmp].y)){ gx = doors[tmp].x; gy = doors[tmp].y; } tmp++; } /* here gx == FAR e.g. when dog is in a vault */ if(gx == FAR || (gx == omx && gy == omy)){ gx = u.ux; gy = u.uy; } #endif /* QUEST */ } appr = (udist >= 9) ? 1 : (mtmp->mflee) ? -1 : 0; if(after && udist <= 4 && gx == u.ux && gy == u.uy) return(0); if(udist > 1){ if (!IS_ROOM(levl[(int)u.ux][(int)u.uy].typ) || !rn2(4) || whappr || (mtmp->minvent && rn2((int) edog->apport))) appr = 1; } /* if you have dog food he'll follow you more closely */ if (appr == 0) { obj = invent; while(obj){ if(obj->otyp == TRIPE_RATION){ appr = 1; break; } obj = obj->nobj; } } } else appr = 1; /* gtyp != UNDEF */ if(mtmp->mconf) appr = 0; if(gx == u.ux && gy == u.uy && (dogroom != uroom || dogroom < 0)){ coord *cp; cp = gettrack(omx,omy); if(cp){ gx = cp->x; gy = cp->y; } } nix = omx; niy = omy; cnt = mfndpos(mtmp,poss,info,ALLOW_M | ALLOW_TRAPS); chcnt = 0; chi = -1; for(i=0; i<cnt; i++){ nx = poss[i].x; ny = poss[i].y; if(info[i] & ALLOW_M){ mtmp2 = m_at(nx,ny); if(mtmp2->data->mlevel >= mdat->mlevel+2 || mtmp2->data->mlet == 'c') continue; if(after) return(0); /* hit only once each move */ if(hitmm(mtmp, mtmp2) == 1 && rn2(4) && mtmp2->mlstmv != moves && hitmm(mtmp2,mtmp) == 2) return(2); return(0); } /* dog avoids traps */ /* but perhaps we have to pass a trap in order to follow @ */ if((info[i] & ALLOW_TRAPS) && (trap = t_at(nx,ny))){ if(!trap->tseen && rn2(40)) continue; if(rn2(10)) continue; } /* dog eschewes cursed objects */ /* but likes dog food */ obj = fobj; while(obj){ if(obj->ox != nx || obj->oy != ny) goto nextobj; if(obj->cursed) goto nxti; if(obj->olet == FOOD_SYM && (otyp = dogfood(obj)) < MANFOOD && (otyp < ACCFOOD || edog->hungrytime <= moves)){ /* Note: our dog likes the food so much that he might eat it even when it conceals a cursed object */ nix = nx; niy = ny; chi = i; eatobj: edog->eattime = moves + obj->quan * objects[obj->otyp].oc_delay; if(edog->hungrytime < moves) edog->hungrytime = moves; edog->hungrytime += 5*obj->quan * objects[obj->otyp].nutrition; mtmp->mconf = 0; if(cansee(nix,niy)) pline("%s ate %s.", Monnam(mtmp), doname(obj)); /* perhaps this was a reward */ if(otyp != CADAVER) edog->apport += 200/(edog->dropdist+moves-edog->droptime); delobj(obj); goto newdogpos; } nextobj: obj = obj->nobj; } for(j=0; j<MTSZ && j<cnt-1; j++) if(nx == mtmp->mtrack[j].x && ny == mtmp->mtrack[j].y) if(rn2(4*(cnt-j))) goto nxti; /* Some stupid C compilers cannot compute the whole expression at once. */ nearer = GDIST(nx,ny); nearer -= GDIST(nix,niy); nearer *= appr; if((nearer == 0 && !rn2(++chcnt)) || nearer<0 || (nearer > 0 && !whappr && ((omx == nix && omy == niy && !rn2(3)) || !rn2(12)) )){ nix = nx; niy = ny; if(nearer < 0) chcnt = 0; chi = i; } nxti: ; } newdogpos: if(nix != omx || niy != omy){ if(info[chi] & ALLOW_U){ (void) hitu(mtmp, d(mdat->damn, mdat->damd)+1); return(0); } mtmp->mx = nix; mtmp->my = niy; for(j=MTSZ-1; j>0; j--) mtmp->mtrack[j] = mtmp->mtrack[j-1]; mtmp->mtrack[0].x = omx; mtmp->mtrack[0].y = omy; } if(mintrap(mtmp) == 2) /* he died */ return(2); pmon(mtmp); return(1); }
int init_kill(void) { FILE *killf; comp_kill_header header; comp_kill_entry entry; register kill_list_entry *kl; register kill_group_regexp *tb; register group_header *gh; time_t kill_age, comp_age; register long n; int first_try = 1; Loop_Groups_Header(gh) gh->kill_list = NULL; kill_age = file_exist(relative(nn_directory, KILL_FILE), "frw"); if (kill_age == 0) return 0; comp_age = file_exist(relative(nn_directory, COMPILED_KILL), "fr"); again: if (comp_age < kill_age && !compile_kill_file()) return 0; kill_tab = NULL; kill_patterns = NULL; group_regexp_table = NULL; regexp_table_size = 0; killf = open_file(relative(nn_directory, COMPILED_KILL), OPEN_READ); if (killf == NULL) return 0; if (fread((char *) &header, sizeof(header), 1, killf) != 1) goto err; /* MAGIC check: format changed or using different hardware */ if (header.ckh_magic != COMP_KILL_MAGIC) goto err; #ifndef NOV /* DB check: if database is rebuilt, group numbers may change */ if (header.ckh_db_check != master.db_created) goto err; #else /* ugly hack for NOV as there isn't a master to check */ if (first_try) goto err; #endif if (header.ckh_entries == 0) { fclose(killf); kill_file_loaded = 1; return 0; } if (header.ckh_pattern_size > 0) { kill_patterns = newstr(header.ckh_pattern_size); fseek(killf, header.ckh_entries * sizeof(entry), 1); if (fread(kill_patterns, sizeof(char), (int) header.ckh_pattern_size, killf) != header.ckh_pattern_size) goto err; } else kill_patterns = newstr(1); kill_tab = newobj(kill_list_entry, header.ckh_entries); if ((regexp_table_size = header.ckh_regexp_size)) group_regexp_table = newobj(kill_group_regexp, header.ckh_regexp_size); tb = group_regexp_table; fseek(killf, sizeof(header), 0); for (n = header.ckh_entries, kl = kill_tab; --n >= 0; kl++) { if (fread((char *) &entry, sizeof(entry), 1, killf) != 1) goto err; if (header.ckh_pattern_size <= entry.ck_pattern_index || entry.ck_pattern_index < 0) goto err; kl->kill_pattern = kill_patterns + entry.ck_pattern_index; kl->kill_flag = entry.ck_flag; if (kl->kill_flag & KILL_ON_REGEXP) kl->kill_regexp = regcomp(kl->kill_pattern); else kl->kill_regexp = NULL; if (kl->kill_flag & GROUP_REGEXP) { if (kl->kill_flag & GROUP_REGEXP_HDR) { if (header.ckh_pattern_size <= entry.ck_group || entry.ck_group < 0) goto err; tb->group_regexp = regcomp(kill_patterns + entry.ck_group); } else tb->group_regexp = NULL; tb->kill_entry = kl; tb++; } else if (entry.ck_group >= 0) { gh = ACTIVE_GROUP(entry.ck_group); kl->next_kill = (kill_list_entry *) (gh->kill_list); gh->kill_list = (char *) kl; } else { kl->next_kill = global_kill_list; global_kill_list = kl; } } fclose(killf); kill_file_loaded = 1; return 1; err: if (group_regexp_table != NULL) freeobj(group_regexp_table); if (kill_patterns != NULL) freeobj(kill_patterns); if (kill_tab != NULL) freeobj(kill_tab); fclose(killf); rm_kill_file(); if (first_try) { first_try = 0; comp_age = 0; goto again; } strcpy(delayed_msg, "Error in compiled kill file (ignored)"); Loop_Groups_Header(gh) gh->kill_list = NULL; global_kill_list = NULL; group_regexp_table = NULL; return 0; }
// returns 1 when something was stolen // (or at least, when N should flee now) // avoid stealing the object stealoid int steal(struct monst *mtmp) { struct obj *otmp; int tmp; int named = 0; if (!invent) { if (Blind) pline("Somebody tries to rob you, but finds nothing to steal."); else pline("%s tries to rob you, but she finds nothing to steal!", Monnam(mtmp)); return 1; // let her flee } tmp = 0; for (otmp = invent; otmp; otmp = otmp->nobj) if (otmp != uarm2) tmp += ((otmp->owornmask & (W_ARMOR | W_RING)) ? 5 : 1); tmp = rn2(tmp); for (otmp = invent; otmp; otmp = otmp->nobj) if (otmp != uarm2) if ((tmp -= ((otmp->owornmask & (W_ARMOR | W_RING)) ? 5 : 1)) < 0) break; if (!otmp) { impossible("Steal fails!"); return 0; } if (otmp->o_id == stealoid) return 0; if ((otmp->owornmask & (W_ARMOR | W_RING))) { switch (otmp->olet) { case RING_SYM: ringoff(otmp); break; case ARMOR_SYM: if (multi < 0 || otmp == uarms) { setworn((struct obj *) 0, otmp->owornmask & W_ARMOR); break; } { int curssv = otmp->cursed; otmp->cursed = 0; stop_occupation(); pline("%s seduces you and %s off your %s.", Amonnam(mtmp, Blind ? "gentle" : "beautiful"), otmp->cursed ? "helps you to take" : "you start taking", (otmp == uarmg) ? "gloves" : (otmp == uarmh) ? "helmet" : "armor"); named++; (void) armoroff(otmp); otmp->cursed = curssv; if (multi < 0) { // multi = 0; // nomovemsg = 0; // afternmv = 0; stealoid = otmp->o_id; stealmid = mtmp->m_id; afternmv = stealarm; return 0; } break; } default: impossible("Tried to steal a strange worn thing."); } } else if (otmp == uwep) setuwep((struct obj *) 0); if (otmp->olet == CHAIN_SYM) { impossible("How come you are carrying that chain?"); } if (Punished && otmp == uball) { Punished = 0; freeobj(uchain); free((char *) uchain); uchain = (struct obj *) 0; uball->spe = 0; uball = (struct obj *) 0; // superfluous } freeinv(otmp); pline("%s stole %s.", named ? "She" : Monnam(mtmp), doname(otmp)); mpickobj(mtmp, otmp); return multi < 0 ? 0 : 1; }
/* * shk_move: return 1: he moved 0: he didnt -1: let m_move do it */ int shk_move(struct monst *shkp) { struct monst *mtmp; struct permonst *mdat = shkp->data; xchar gx, gy, omx, omy, nx, ny, nix, niy; schar appr, i; int udist; int z; schar shkroom, chi, chcnt, cnt; boolean uondoor = 0, satdoor, avoid = 0, badinv; coord poss[9]; int info[9]; struct obj *ib = NULL; omx = shkp->mx; omy = shkp->my; if ((udist = dist(omx, omy)) < 3) { if (ANGRY(shkp)) { hitu(shkp, d(mdat->damn, mdat->damd) + 1); return (0); } if (ESHK(shkp)->following) { if (strncmp(ESHK(shkp)->customer, plname, PL_NSIZ)) { pline("Hello %s! I was looking for %s.", plname, ESHK(shkp)->customer); ESHK(shkp)->following = 0; return (0); } if (!ESHK(shkp)->robbed) { /* impossible? */ ESHK(shkp)->following = 0; return (0); } if (moves > followmsg + 4) { pline("Hello %s! Didn't you forget to pay?", plname); followmsg = moves; } if (udist < 2) return (0); } } shkroom = inroom(omx, omy); appr = 1; gx = ESHK(shkp)->shk.x; gy = ESHK(shkp)->shk.y; satdoor = (gx == omx && gy == omy); if (ESHK(shkp)->following || ((z = holetime()) >= 0 && z * z <= udist)) { gx = u.ux; gy = u.uy; if (shkroom < 0 || shkroom != inroom(u.ux, u.uy)) if (udist > 4) return (-1); /* leave it to m_move */ } else if (ANGRY(shkp)) { long saveBlind = Blind; Blind = 0; if (shkp->mcansee && !Invis && cansee(omx, omy)) { gx = u.ux; gy = u.uy; } Blind = saveBlind; avoid = FALSE; } else { #define GDIST(x, y) ((x - gx) * (x - gx) + (y - gy) * (y - gy)) if (Invis) avoid = FALSE; else { uondoor = (u.ux == ESHK(shkp)->shd.x && u.uy == ESHK(shkp)->shd.y); if (uondoor) { if (ESHK(shkp)->billct) pline("Hello %s! Will you please pay before leaving?", plname); badinv = (carrying(PICK_AXE) || carrying(ICE_BOX)); if (satdoor && badinv) return (0); avoid = !badinv; } else { avoid = (u.uinshop && dist(gx, gy) > 8); badinv = FALSE; } if (((!ESHK(shkp)->robbed && !ESHK(shkp)->billct) || avoid) && GDIST(omx, omy) < 3) { if (!badinv && !online(omx, omy)) return (0); if (satdoor) appr = gx = gy = 0; } } } if (omx == gx && omy == gy) return (0); if (shkp->mconf) { avoid = FALSE; appr = 0; } nix = omx; niy = omy; cnt = mfndpos(shkp, poss, info, ALLOW_SSM); if (avoid && uondoor) { /* perhaps we cannot avoid him */ for (i = 0; i < cnt; i++) if (!(info[i] & NOTONL)) goto notonl_ok; avoid = FALSE; notonl_ok: ; } chi = -1; chcnt = 0; for (i = 0; i < cnt; i++) { nx = poss[i].x; ny = poss[i].y; if (levl[nx][ny].typ == ROOM || shkroom != ESHK(shkp)->shoproom || ESHK(shkp)->following) { #ifdef STUPID /* cater for stupid compilers */ int zz; #endif /* STUPID */ if (uondoor && (ib = sobj_at(ICE_BOX, nx, ny))) { nix = nx; niy = ny; chi = i; break; } if (avoid && (info[i] & NOTONL)) continue; if ((!appr && !rn2(++chcnt)) || #ifdef STUPID (appr && (zz = GDIST(nix, niy)) && zz > GDIST(nx, ny)) #else (appr && GDIST(nx, ny) < GDIST(nix, niy)) #endif /* STUPID */ ) { nix = nx; niy = ny; chi = i; } } } if (nix != omx || niy != omy) { if (info[chi] & ALLOW_M) { mtmp = m_at(nix, niy); if (hitmm(shkp, mtmp) == 1 && rn2(3) && hitmm(mtmp, shkp) == 2) return (2); return (0); } else if (info[chi] & ALLOW_U) { hitu(shkp, d(mdat->damn, mdat->damd) + 1); return (0); } shkp->mx = nix; shkp->my = niy; pmon(shkp); if (ib) { freeobj(ib); mpickobj(shkp, ib); } return (1); } return (0); }
int doread() { struct obj *scroll; boolean confused = (Confusion != 0); boolean known = FALSE; scroll = getobj("?", "read"); if(!scroll) return(0); if(!scroll->dknown && Blind) { pline("Being blind, you cannot read the formula on the scroll."); return(0); } if(Blind) pline("As you pronounce the formula on it, the scroll disappears."); else pline("As you read the scroll, it disappears."); if(confused) pline("Being confused, you mispronounce the magic words ... "); switch(scroll->otyp) { #ifdef MAIL case SCR_MAIL: readmail(/* scroll */); break; #endif /* MAIL */ case SCR_ENCHANT_ARMOR: { struct obj *otmp = some_armor(); if(!otmp) { strange_feeling(scroll,"Your skin glows then fades."); return(1); } if(confused) { pline("Your %s glows silver for a moment.", objects[otmp->otyp].oc_name); otmp->rustfree = 1; break; } if(otmp->spe > 3 && rn2(otmp->spe)) { pline("Your %s glows violently green for a while, then evaporates.", objects[otmp->otyp].oc_name); useup(otmp); break; } pline("Your %s glows green for a moment.", objects[otmp->otyp].oc_name); otmp->cursed = 0; otmp->spe++; break; } case SCR_DESTROY_ARMOR: if(confused) { struct obj *otmp = some_armor(); if(!otmp) { strange_feeling(scroll,"Your bones itch."); return(1); } pline("Your %s glows purple for a moment.", objects[otmp->otyp].oc_name); otmp->rustfree = 0; break; } if(uarm) { pline("Your armor turns to dust and falls to the floor!"); useup(uarm); } else if(uarmh) { pline("Your helmet turns to dust and is blown away!"); useup(uarmh); } else if(uarmg) { pline("Your gloves vanish!"); useup(uarmg); selftouch("You"); } else { strange_feeling(scroll,"Your skin itches."); return(1); } break; case SCR_CONFUSE_MONSTER: if(confused) { pline("Your hands begin to glow purple."); Confusion += rnd(100); } else { pline("Your hands begin to glow blue."); u.umconf = 1; } break; case SCR_SCARE_MONSTER: { int ct = 0; struct monst *mtmp; for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) if(cansee(mtmp->mx,mtmp->my)) { if(confused) mtmp->mflee = mtmp->mfroz = mtmp->msleep = 0; else mtmp->mflee = 1; ct++; } if(!ct) { if(confused) pline("You hear sad wailing in the distance."); else pline("You hear maniacal laughter in the distance."); } break; } case SCR_BLANK_PAPER: if(confused) pline("You see strange patterns on this scroll."); else pline("This scroll seems to be blank."); break; case SCR_REMOVE_CURSE: { struct obj *obj; if(confused) pline("You feel like you need some help."); else pline("You feel like someone is helping you."); for(obj = invent; obj ; obj = obj->nobj) if(obj->owornmask) obj->cursed = confused; if(Punished && !confused) { Punished = 0; freeobj(uchain); unpobj(uchain); free(uchain); uball->spe = 0; uball->owornmask &= ~W_BALL; uchain = uball = (struct obj *) 0; } break; } case SCR_CREATE_MONSTER: { int cnt = 1; if(!rn2(73)) cnt += rnd(4); if(confused) cnt += 12; while(cnt--) (void) makemon(confused ? PM_ACID_BLOB : (struct permonst *) 0, u.ux, u.uy); break; } case SCR_ENCHANT_WEAPON: if(uwep && confused) { pline("Your %s glows silver for a moment.", objects[uwep->otyp].oc_name); uwep->rustfree = 1; } else if(!chwepon(scroll, 1)) /* tests for !uwep */ return(1); break; case SCR_DAMAGE_WEAPON: if(uwep && confused) { pline("Your %s glows purple for a moment.", objects[uwep->otyp].oc_name); uwep->rustfree = 0; } else if(!chwepon(scroll, -1)) /* tests for !uwep */ return(1); break; case SCR_TAMING: { int i,j; int bd = confused ? 5 : 1; struct monst *mtmp; for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++) if ((mtmp = m_at(u.ux+i, u.uy+j))) (void) tamedog(mtmp, NULL); break; } case SCR_GENOCIDE: { extern char genocided[], fut_geno[]; char buf[BUFSZ]; struct monst *mtmp, *mtmp2; pline("You have found a scroll of genocide!"); known = TRUE; if(confused) *buf = u.usym; else do { pline("What monster do you want to genocide (Type the letter)? "); getlin(buf); } while(strlen(buf) != 1 || !monstersym(*buf)); if(!strchr(fut_geno, *buf)) charcat(fut_geno, *buf); if(!strchr(genocided, *buf)) charcat(genocided, *buf); else { pline("Such monsters do not exist in this world."); break; } for(mtmp = fmon; mtmp; mtmp = mtmp2){ mtmp2 = mtmp->nmon; if(mtmp->data->mlet == *buf) mondead(mtmp); } pline("Wiped out all %c's.", *buf); if(*buf == u.usym) { killer = "scroll of genocide"; u.uhp = -1; } break; } case SCR_LIGHT: if(!Blind) known = TRUE; litroom(!confused); break; case SCR_TELEPORTATION: if(confused) level_tele(); else { #ifdef QUEST int oux = u.ux, ouy = u.uy; tele(); if(dist(oux, ouy) > 100) known = TRUE; #else /* QUEST */ int uroom = inroom(u.ux, u.uy); tele(); if(uroom != inroom(u.ux, u.uy)) known = TRUE; #endif /* QUEST */ } break; case SCR_GOLD_DETECTION: /* Unfortunately this code has become slightly less elegant, now that gold and traps no longer are of the same type. */ if(confused) { struct trap *ttmp; if(!ftrap) { strange_feeling(scroll, "Your toes stop itching."); return(1); } else { for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) if(ttmp->tx != u.ux || ttmp->ty != u.uy) goto outtrapmap; /* only under me - no separate display required */ pline("Your toes itch!"); break; outtrapmap: cls(); for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) at(ttmp->tx, ttmp->ty, '$'); prme(); pline("You feel very greedy!"); } } else { struct gold *gtmp; if(!fgold) { strange_feeling(scroll, "You feel materially poor."); return(1); } else { known = TRUE; for(gtmp = fgold; gtmp; gtmp = gtmp->ngold) if(gtmp->gx != u.ux || gtmp->gy != u.uy) goto outgoldmap; /* only under me - no separate display required */ pline("You notice some gold between your feet."); break; outgoldmap: cls(); for(gtmp = fgold; gtmp; gtmp = gtmp->ngold) at(gtmp->gx, gtmp->gy, '$'); prme(); pline("You feel very greedy, and sense gold!"); } } /* common sequel */ more(); docrt(); break; case SCR_FOOD_DETECTION: { int ct = 0, ctu = 0; struct obj *obj; char foodsym = confused ? POTION_SYM : FOOD_SYM; for(obj = fobj; obj; obj = obj->nobj) if(obj->olet == FOOD_SYM) { if(obj->ox == u.ux && obj->oy == u.uy) ctu++; else ct++; } if(!ct && !ctu) { strange_feeling(scroll,"Your nose twitches."); return(1); } else if(!ct) { known = TRUE; pline("You smell %s close nearby.", confused ? "something" : "food"); } else { known = TRUE; cls(); for(obj = fobj; obj; obj = obj->nobj) if(obj->olet == foodsym) at(obj->ox, obj->oy, FOOD_SYM); prme(); pline("Your nose tingles and you smell %s!", confused ? "something" : "food"); more(); docrt(); } break; } case SCR_IDENTIFY: /* known = TRUE; */ if(confused) pline("You identify this as an identify scroll."); else pline("This is an identify scroll."); useup(scroll); objects[SCR_IDENTIFY].oc_name_known = 1; if(!confused) while( !ggetobj("identify", identify, rn2(5) ? 1 : rn2(5)) && invent ); return(1); case SCR_MAGIC_MAPPING: { struct rm *lev; int num, zx, zy; known = TRUE; pline("On this scroll %s a map!", confused ? "was" : "is"); for(zy = 0; zy < ROWNO; zy++) for(zx = 0; zx < COLNO; zx++) { if(confused && rn2(7)) continue; lev = &(levl[zx][zy]); if((num = lev->typ) == 0) continue; if(num == SCORR) { lev->typ = CORR; lev->scrsym = CORR_SYM; } else if(num == SDOOR) { lev->typ = DOOR; lev->scrsym = '+'; /* do sth in doors ? */ } else if(lev->seen) continue; #ifndef QUEST if(num != ROOM) #endif /* QUEST */ { lev->seen = lev->new = 1; if(lev->scrsym == ' ' || !lev->scrsym) newsym(zx,zy); else on_scr(zx,zy); } } break; } case SCR_AMNESIA: { int zx, zy; known = TRUE; for(zx = 0; zx < COLNO; zx++) for(zy = 0; zy < ROWNO; zy++) if(!confused || rn2(7)) if(!cansee(zx,zy)) levl[zx][zy].seen = 0; docrt(); pline("Thinking of Maud you forget everything else."); break; } case SCR_FIRE: { int num; struct monst *mtmp; known = TRUE; if(confused) { pline("The scroll catches fire and you burn your hands."); losehp(1, "scroll of fire"); } else { pline("The scroll erupts in a tower of flame!"); if(Fire_resistance) pline("You are uninjured."); else { num = rnd(6); u.uhpmax -= num; losehp(num, "scroll of fire"); } } num = (2*num + 1)/3; for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { if(dist(mtmp->mx,mtmp->my) < 3) { mtmp->mhp -= num; if(strchr("FY", mtmp->data->mlet)) mtmp->mhp -= 3*num; /* this might well kill 'F's */ if(mtmp->mhp < 1) { killed(mtmp); break; /* primitive */ } } } break; } case SCR_PUNISHMENT: known = TRUE; if(confused) { pline("You feel guilty."); break; } pline("You are being punished for your misbehaviour!"); if(Punished){ pline("Your iron ball gets heavier."); uball->owt += 15; break; } Punished = INTRINSIC; setworn(mkobj_at(CHAIN_SYM, u.ux, u.uy), W_CHAIN); setworn(mkobj_at(BALL_SYM, u.ux, u.uy), W_BALL); uball->spe = 1; /* special ball (see save) */ break; default: impossible("What weird language is this written in? (%u)", scroll->otyp); }
int dothrow() { struct obj *obj; struct monst *mon; int tmp; obj = getobj("#)", "throw"); /* it is also possible to throw food */ /* (or jewels, or iron balls ... ) */ if(!obj || !getdir(1)) /* ask "in what direction?" */ return(0); if(obj->owornmask & (W_ARMOR | W_RING)){ pline("You can't throw something you are wearing."); return(0); } u_wipe_engr(2); if(obj == uwep){ if(obj->cursed){ pline("Your weapon is welded to your hand."); return(1); } if(obj->quan > 1) setuwep(splitobj(obj, 1)); else setuwep((struct obj *) 0); } else if(obj->quan > 1) (void) splitobj(obj, 1); freeinv(obj); if(u.uswallow) { mon = u.ustuck; bhitpos.x = mon->mx; bhitpos.y = mon->my; } else if(u.dz) { if(u.dz < 0) { pline("%s hits the ceiling, then falls back on top of your head.", Doname(obj)); /* note: obj->quan == 1 */ if(obj->olet == POTION_SYM) potionhit(&youmonst, obj); else { if(uarmh) pline("Fortunately, you are wearing a helmet!"); losehp(uarmh ? 1 : rnd((int)(obj->owt)), "falling object"); dropy(obj); } } else { pline("%s hits the floor.", Doname(obj)); if(obj->otyp == EXPENSIVE_CAMERA) { pline("It is shattered in a thousand pieces!"); obfree(obj, Null(obj)); } else if(obj->otyp == EGG) { pline("\"Splash!\""); obfree(obj, Null(obj)); } else if(obj->olet == POTION_SYM) { pline("The flask breaks, and you smell a peculiar odor ..."); potionbreathe(obj); obfree(obj, Null(obj)); } else { dropy(obj); } } return(1); } else if(obj->otyp == BOOMERANG) { mon = boomhit(u.dx, u.dy); if(mon == &youmonst) { /* the thing was caught */ (void) addinv(obj); return(1); } } else { if(obj->otyp == PICK_AXE && shkcatch(obj)) return(1); mon = bhit(u.dx, u.dy, (obj->otyp == ICE_BOX) ? 1 : (!Punished || obj != uball) ? 8 : !u.ustuck ? 5 : 1, obj->olet, NULL, NULL, obj); } if(mon) { /* awake monster if sleeping */ wakeup(mon); if(obj->olet == WEAPON_SYM) { tmp = -1+u.ulevel+mon->data->ac+abon(); if(obj->otyp < ROCK) { if(!uwep || uwep->otyp != obj->otyp+(BOW-ARROW)) tmp -= 4; else { tmp += uwep->spe; } } else if(obj->otyp == BOOMERANG) tmp += 4; tmp += obj->spe; if(u.uswallow || tmp >= rnd(20)) { if(hmon(mon,obj,1) == TRUE){ /* mon still alive */ #ifndef NOWORM cutworm(mon,bhitpos.x,bhitpos.y,obj->otyp); #endif /* NOWORM */ } else mon = 0; /* weapons thrown disappear sometimes */ if(obj->otyp < BOOMERANG && rn2(3)) { /* check bill; free */ obfree(obj, (struct obj *) 0); return(1); } } else miss(objects[obj->otyp].oc_name, mon); } else if(obj->otyp == HEAVY_IRON_BALL) { tmp = -1+u.ulevel+mon->data->ac+abon(); if(!Punished || obj != uball) tmp += 2; if(u.utrap) tmp -= 2; if(u.uswallow || tmp >= rnd(20)) { if(hmon(mon,obj,1) == FALSE) mon = 0; /* he died */ } else miss("iron ball", mon); } else if(obj->olet == POTION_SYM && u.ulevel > rn2(15)) { potionhit(mon, obj); return(1); } else { if(cansee(bhitpos.x,bhitpos.y)) pline("You miss %s.",monnam(mon)); else pline("You miss it."); if(obj->olet == FOOD_SYM && mon->data->mlet == 'd') if(tamedog(mon,obj)) return(1); if(obj->olet == GEM_SYM && mon->data->mlet == 'u' && !mon->mtame){ if(obj->dknown && objects[obj->otyp].oc_name_known){ if(objects[obj->otyp].g_val > 0){ u.uluck += 5; goto valuable; } else { pline("%s is not interested in your junk.", Monnam(mon)); } } else { /* value unknown to @ */ u.uluck++; valuable: if(u.uluck > LUCKMAX) /* dan@ut-ngp */ u.uluck = LUCKMAX; pline("%s graciously accepts your gift.", Monnam(mon)); mpickobj(mon, obj); rloc(mon); return(1); } } } } /* the code following might become part of dropy() */ if(obj->otyp == CRYSKNIFE) obj->otyp = WORM_TOOTH; obj->ox = bhitpos.x; obj->oy = bhitpos.y; obj->nobj = fobj; fobj = obj; /* prevent him from throwing articles to the exit and escaping */ /* subfrombill(obj); */ stackobj(obj); if(Punished && obj == uball && (bhitpos.x != u.ux || bhitpos.y != u.uy)){ freeobj(uchain); unpobj(uchain); if(u.utrap){ if(u.utraptype == TT_PIT) pline("The ball pulls you out of the pit!"); else { long side = rn2(3) ? LEFT_SIDE : RIGHT_SIDE; pline("The ball pulls you out of the bear trap."); pline("Your %s leg is severely damaged.", (side == LEFT_SIDE) ? "left" : "right"); set_wounded_legs(side, 500+rn2(1000)); losehp(2, "thrown ball"); } u.utrap = 0; } unsee(); uchain->nobj = fobj; fobj = uchain; u.ux = uchain->ox = bhitpos.x - u.dx; u.uy = uchain->oy = bhitpos.y - u.dy; setsee(); (void) inshop(); } if(cansee(bhitpos.x, bhitpos.y)) prl(bhitpos.x,bhitpos.y); return(1); }
int set_variable(char *variable, int on, char *val_string) { int value; register struct variable_defs *var; if (strncmp(variable, "no", 2) == 0) { on = !on; variable += 2; if (variable[0] == '-') variable++; } if ((var = lookup_variable(variable)) == NULL) return 0; if (!in_init && (var->var_flags & (V_INIT | V_SAFE))) { if (var->var_flags & V_INIT) { msg("'%s' can only be set in the init file", variable); return 0; } if (shell_restrictions) { msg("Restricted operation - cannot change"); return 0; } } if (var->var_flags & V_LOCKED) { msg("Variable '%s' is locked", variable); return 0; } if (!on || val_string == NULL) value = 0; else value = atoi(val_string); var->var_flags |= V_MODIFIED; switch (VAR_TYPE) { case V_STRING: if (on) adjust(val_string); switch (VAR_OP) { case 0: STR_VAR = (on && val_string) ? copy_str(val_string) : (char *) NULL; break; case 1: strcpy(CBUF_VAR, (on && val_string) ? val_string : ""); break; case 2: if (on) { char exp_buf[FILENAME]; if (val_string) { if (expand_file_name(exp_buf, val_string, 1)) STR_VAR = home_relative(exp_buf); } } else STR_VAR = (char *) NULL; break; case 3: case 4: if (!on || val_string == NULL) { msg("Cannot unset string `%s'", variable); break; } if (VAR_OP == 4) { char exp_buf[FILENAME]; if (expand_file_name(exp_buf, val_string, 1)) { STR_VAR = copy_str(exp_buf); break; } } STR_VAR = copy_str(val_string); break; case 5: STR_VAR = (on && val_string) ? copy_str(val_string) : ""; break; } break; case V_BOOLEAN: adjust(val_string); if (val_string && *val_string != NUL) { if (val_string[0] == 'o') on = val_string[1] == 'n'; /* on */ else on = val_string[0] == 't'; /* true */ } switch (VAR_OP) { case 0: BOOL_VAR = on; break; case 1: BOOL_VAR = on; return 1; case 2: if (BOOL_VAR) { /* don't change if already ok */ if (!on) break; } else if (on) break; BOOL_VAR = !on; if (!in_init) { sort_articles(BOOL_VAR ? 0 : -1); return 1; } break; case 4: BOOL_VAR = !on; break; } break; case V_INTEGER: switch (VAR_OP) { case 0: case 1: INT_VAR = value; break; case 2: case 3: if (!on) value = -1; INT_VAR = value; break; } return (VAR_OP & 1); case V_KEY: switch (VAR_OP) { case 0: if (val_string) { if (*val_string) adjust(val_string + 1); /* #N is valid */ KEY_VAR = parse_key(val_string); } break; } break; case V_SPECIAL: switch (VAR_OP) { case 1: if (val_string) { adjust(val_string); news_record = home_relative(val_string); mail_record = news_record; var->var_flags &= ~V_MODIFIED; lookup_variable("mail-record")->var_flags |= V_MODIFIED; lookup_variable("news-record")->var_flags |= V_MODIFIED; } break; case 2: also_read_articles = on; article_limit = (on && value > 0) ? value : -1; break; case 3: { struct chset *csp; struct variable_defs *dbvar; dbvar = lookup_variable("data-bits"); if (on && val_string) { if ((csp = getchset(val_string)) == NULL) msg("Illegal value for `%s' variable", variable); else { curchset = csp; data_bits = csp->cs_width ? csp->cs_width : 7; dbvar->var_flags &= ~V_MODIFIED; } } else msg("Cannot unset special `%s' variable", variable); } break; } break; case V_CODES: { char codes[80], code[16], *sp, *cp, *vs; if (val_string == NULL) on = 0; if (on) { adjust(val_string); if (val_string[0] == NUL) on = 0; } if (on) { sp = codes; vs = val_string; while (*vs) { while (*vs && (!isascii(*vs) || isspace(*vs))) vs++; if (*vs == NUL) break; cp = code; while (*vs && isascii(*vs) && !isspace(*vs)) *cp++ = *vs++; *cp = NUL; *sp++ = parse_key(code); } *sp = NUL; if (codes[0] == NUL) on = 0; } freeobj(code_strings[VAR_OP]); code_strings[VAR_OP] = on ? copy_str(val_string) : NULL; STR_VAR = on ? copy_str(codes) : (char *) NULL; break; } } return 0; }