home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
games
/
volume16
/
nethack31
/
part59
< prev
next >
Wrap
Internet Message Format
|
1993-02-04
|
59KB
Path: uunet!news.tek.com!master!saab!billr
From: billr@saab.CNA.TEK.COM (Bill Randle)
Newsgroups: comp.sources.games
Subject: v16i067: nethack31 - display oriented dungeons & dragons (Ver. 3.1), Part59/108
Message-ID: <4370@master.CNA.TEK.COM>
Date: 1 Feb 93 19:45:40 GMT
Sender: news@master.CNA.TEK.COM
Lines: 2250
Approved: billr@saab.CNA.TEK.COM
Xref: uunet comp.sources.games:1617
Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
Posting-number: Volume 16, Issue 67
Archive-name: nethack31/Part59
Supersedes: nethack3p9: Volume 10, Issue 46-102
Environment: Amiga, Atari, Mac, MS-DOS, OS2, Unix, VMS, X11
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 59 (of 108)."
# Contents: src/dokick.c sys/amiga/splitter/split.doc
# win/tty/termcap.c
# Wrapped by billr@saab on Wed Jan 27 16:09:10 1993
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'src/dokick.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/dokick.c'\"
else
echo shar: Extracting \"'src/dokick.c'\" \(32287 characters\)
sed "s/^X//" >'src/dokick.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)dokick.c 3.1 92/10/06 */
X/* Copyright (c) Izchak Miller, Mike Stephenson, Steve Linhart, 1989. */
X/* NetHack may be freely redistributed. See license for details. */
X
X#include "hack.h"
X#include "eshk.h"
X
X#ifndef POLYSELF
X# define martial() (pl_character[0] == 'S' || pl_character[0] == 'P')
X#else
X# define is_bigfoot(x) ((x) == &mons[PM_SASQUATCH])
X# define martial() (pl_character[0] == 'S' || pl_character[0] == 'P' \
X || is_bigfoot(uasmon))
X#endif
X
Xstatic struct rm NEARDATA *maploc;
X
Xextern boolean notonhead; /* for long worms */
X
Xstatic void FDECL(kickdmg, (struct monst *, BOOLEAN_P));
Xstatic void FDECL(kick_monster, (XCHAR_P, XCHAR_P));
Xstatic int FDECL(kick_object, (XCHAR_P, XCHAR_P));
Xstatic char *NDECL(kickstr);
Xstatic void FDECL(otransit_msg, (struct obj *, XCHAR_P, BOOLEAN_P, int));
Xstatic const char *FDECL(gate_str, (XCHAR_P));
Xstatic void FDECL(drop_to, (coord *, XCHAR_P));
X
Xstatic struct obj NEARDATA *kickobj;
X
X#define IS_SHOP(x) (rooms[x].rtype >= SHOPBASE)
X
Xstatic void
Xkickdmg(mon, clumsy)
Xregister struct monst *mon;
Xregister boolean clumsy;
X{
X register int mdx, mdy;
X register int dmg = ( ACURRSTR + ACURR(A_DEX) + ACURR(A_CON) )/ 15;
X
X /* excessive wt affects dex, so it affects dmg */
X if(clumsy) dmg = dmg/2;
X
X /* kicking a dragon or an elephant will not harm it */
X if(thick_skinned(mon->data)) dmg = 0;
X
X /* a good kick exercises your dex */
X exercise(A_DEX, TRUE);
X
X /* squeeze some guilt feelings... */
X if(mon->mtame) {
X#ifdef SOUNDS
X if (rn2(10)) yelp(mon);
X else growl(mon); /* give them a moment's worry */
X#endif
X mon->mtame--;
X if(!mon->mtame) newsym(mon->mx, mon->my);
X mon->mflee = mon->mtame ? 1 : 0;
X#ifdef HISX
X mon->mfleetim = mon->mfleetim + (dmg ? rnd(dmg) : 1);
X#else
X mon->mfleetim += (dmg ? rnd(dmg) : 1);
X#endif
X }
X
X if (dmg)
X mon->mhp -= (!martial() ? rnd(dmg) :
X rnd(dmg)+rnd(ACURR(A_DEX)/2));
X if(mon->mhp < 1) {
X (void) passive(mon, TRUE, 0, TRUE);
X killed(mon);
X return;
X }
X if(martial() && !bigmonst(mon->data) && !rn2(3) && mon->mcanmove) {
X /* see if the monster has a place to move into */
X mdx = mon->mx + u.dx;
X mdy = mon->my + u.dy;
X if(goodpos(mdx, mdy, mon, mon->data)) {
X pline("%s reels from the blow.", Monnam(mon));
X remove_monster(mon->mx, mon->my);
X place_monster(mon, mdx, mdy);
X newsym(mon->mx, mon->my);
X set_apparxy(mon);
X }
X }
X (void) passive(mon, FALSE, 1, TRUE);
X
X/* it is unchivalrous to attack the defenseless or from behind */
X if (pl_character[0] == 'K' &&
X u.ualign.type == A_LAWFUL && u.ualign.record > -10 &&
X (!mon->mcanmove || mon->msleep || mon->mflee))
X adjalign(-1);
X
X}
X
Xstatic void
Xkick_monster(x, y)
Xregister xchar x, y;
X{
X register boolean clumsy = FALSE;
X register struct monst *mon = m_at(x, y);
X register int i, j;
X
X bhitpos.x = x;
X bhitpos.y = y;
X if(special_case(mon)) return;
X setmangry(mon);
X#ifdef POLYSELF
X /* Kick attacks by kicking monsters are normal attacks, not special.
X * If you have >1 kick attack, you get all of them.
X */
X if (attacktype(uasmon, AT_KICK)) {
X schar tmp = find_roll_to_hit(mon);
X for(i=0; i<NATTK; i++) {
X if (uasmon->mattk[i].aatyp == AT_KICK && multi >= 0) {
X /* check multi; maybe they had 2 kicks and the first */
X /* was a kick against a floating eye */
X if (tmp > rnd(20)) {
X int sum;
X
X You("kick %s.", mon_nam(mon));
X sum = damageum(mon, &(uasmon->mattk[i]));
X if (sum == 2)
X (void)passive(mon, 1, 0, TRUE);
X else (void)passive(mon, sum, 1, TRUE);
X } else {
X missum(mon, &(uasmon->mattk[i]));
X (void)passive(mon, 0, 1, TRUE);
X }
X }
X }
X return;
X }
X#endif
X
X /* no need to check POLYSELF since only ghosts, which you can't turn */
X /* into, are noncorporeal */
X if(noncorporeal(mon->data)) {
X Your("kick passes through!");
X return;
X }
X
X if(Levitation && !rn2(3) && verysmall(mon->data) &&
X !is_flyer(mon->data)) {
X pline("Floating in the air, you miss wildly!");
X exercise(A_DEX, FALSE);
X (void) passive(mon, FALSE, 1, TRUE);
X return;
X }
X
X i = -inv_weight();
X j = weight_cap();
X
X if(i < (j*3)/10) {
X if(!rn2((i < j/10) ? 2 : (i < j/5) ? 3 : 4)) {
X if(martial() && !rn2(2)) goto doit;
X Your("clumsy kick does no damage.");
X (void) passive(mon, FALSE, 1, TRUE);
X return;
X }
X if(i < j/10) clumsy = TRUE;
X else if(!rn2((i < j/5) ? 2 : 3)) clumsy = TRUE;
X }
X
X if(Fumbling) clumsy = TRUE;
X
X else if(uarm && objects[uarm->otyp].oc_bulky && ACURR(A_DEX) < rnd(25))
X clumsy = TRUE;
Xdoit:
X You("kick %s.", mon_nam(mon));
X if(!rn2(clumsy ? 3 : 4) && (clumsy || !bigmonst(mon->data)) &&
X mon->mcansee && !mon->mtrapped && !thick_skinned(mon->data) &&
X mon->data->mlet != S_EEL && haseyes(mon->data) && mon->mcanmove &&
X !mon->mstun && !mon->mconf && !mon->msleep &&
X mon->data->mmove >= 12) {
X if(!nohands(mon->data) && !rn2(martial() ? 5 : 3)) {
X pline("%s blocks your %skick.", Monnam(mon),
X clumsy ? "clumsy " : "");
X (void) passive(mon, FALSE, 1, TRUE);
X return;
X } else {
X mnexto(mon);
X if(mon->mx != x || mon->my != y) {
X pline("%s %s, %s evading your %skick.", Monnam(mon),
X (can_teleport(mon->data) ? "teleports" :
X is_floater(mon->data) ? "floats" :
X is_flyer(mon->data) ? "flutters" :
X nolimbs(mon->data) ? "slides" :
X "jumps"),
X clumsy ? "easily" : "nimbly",
X clumsy ? "clumsy " : "");
X (void) passive(mon, FALSE, 1, TRUE);
X return;
X }
X }
X }
X kickdmg(mon, clumsy);
X}
X
X/*
X * Return TRUE if caught (the gold taken care of), FALSE otherwise.
X * The gold object is *not* attached to the fobj chain!
X */
Xboolean
Xghitm(mtmp, gold)
Xregister struct monst *mtmp;
Xregister struct obj *gold;
X{
X if(!likes_gold(mtmp->data) && !mtmp->isshk && !mtmp->ispriest
X#ifdef ARMY
X && !is_mercenary(mtmp->data)
X#endif
X ) {
X wakeup(mtmp);
X } else if (!mtmp->mcanmove) {
X /* too light to do real damage */
X if (canseemon(mtmp))
X pline("The gold hits %s.", mon_nam(mtmp));
X } else {
X mtmp->msleep = 0;
X mtmp->meating = 0;
X if(!rn2(4)) setmangry(mtmp); /* not always pleasing */
X
X /* greedy monsters catch gold */
X if (cansee(mtmp->mx, mtmp->my))
X pline("%s catches the gold.", Monnam(mtmp));
X mtmp->mgold += gold->quan;
X if (mtmp->isshk) {
X long robbed = ESHK(mtmp)->robbed;
X
X if (robbed) {
X robbed -= gold->quan;
X if (robbed < 0) robbed = 0;
X pline("The amount %scovers %s recent losses.",
X !robbed ? "" : "partially ",
X mtmp->female ? "her" : "his");
X ESHK(mtmp)->robbed = robbed;
X if(!robbed)
X make_happy_shk(mtmp, FALSE);
X } else {
X if(mtmp->mpeaceful) {
X ESHK(mtmp)->credit += gold->quan;
X You("have %ld zorkmid%s in credit.",
X ESHK(mtmp)->credit,
X plur(ESHK(mtmp)->credit));
X } else verbalize("Thanks, scum!");
X }
X }
X else if(mtmp->ispriest) {
X if(mtmp->mpeaceful)
X verbalize("Thank you for your contribution.");
X else verbalize("Thanks, scum!");
X }
X else if(is_mercenary(mtmp->data)) {
X if(rn2(3)) {
X if(mtmp->data == &mons[PM_SOLDIER]) {
X if(gold->quan > 100 + (u.ugold + (u.ulevel*rn2(5)))
X /ACURR(A_CHA))
X mtmp->mpeaceful = 1;
X }
X if(mtmp->data == &mons[PM_SERGEANT]) {
X if(gold->quan > 250 + (u.ugold + (u.ulevel*rn2(5)))
X /ACURR(A_CHA))
X mtmp->mpeaceful = 1;
X }
X if(mtmp->data == &mons[PM_LIEUTENANT]) {
X if(gold->quan > 500 + (u.ugold + (u.ulevel*rn2(5)))
X /ACURR(A_CHA))
X mtmp->mpeaceful = 1;
X }
X if(mtmp->data == &mons[PM_CAPTAIN]) {
X if(gold->quan > 750 + (u.ugold + (u.ulevel*rn2(5)))
X /ACURR(A_CHA))
X mtmp->mpeaceful = 1;
X }
X }
X if(mtmp->mpeaceful)
X verbalize("That should do. Now beat it!");
X else verbalize("That's not enough, coward!");
X }
X
X dealloc_obj(gold);
X return(1);
X }
X return(0);
X}
X
Xstatic int
Xkick_object(x, y)
Xxchar x, y;
X{
X int range;
X register struct monst *mon, *shkp;
X register struct obj *otmp;
X struct trap *trap;
X boolean costly, insider, shipit;
X boolean isgold;
X
X /* if a pile, the "top" object gets kicked */
X kickobj = level.objects[x][y];
X
X /* kickobj should always be set due to conditions of call */
X if(!kickobj || kickobj->otyp == BOULDER
X || kickobj == uball || kickobj == uchain)
X return(0);
X
X if((trap = t_at(x,y)) && trap->tseen) {
X if (((trap->ttyp == PIT || trap->ttyp == SPIKED_PIT)
X#ifdef POLYSELF
X && !passes_walls(uasmon)
X#endif
X ) || trap->ttyp == WEB) {
X You("can't kick something that's in a %s!",
X trap->ttyp == WEB ? "web" : "pit");
X return(1);
X }
X }
X
X if(Fumbling && !rn2(3)) {
X Your("clumsy kick missed.");
X return(1);
X }
X
X /* range < 2 means the object will not move. */
X /* maybe dexterity should also figure here. */
X range = (int)((ACURRSTR)/2 - kickobj->owt/40);
X
X if(martial()) range += rnd(3);
X
X /* Mjollnir is magically too heavy to kick */
X if(kickobj->oartifact == ART_MJOLLNIR) range = 1;
X
X /* see if the object has a place to move into */
X if(!ZAP_POS(levl[x+u.dx][y+u.dy].typ) || closed_door(x+u.dx, y+u.dy))
X range = 1;
X
X costly = ((shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) &&
X costly_spot(x, y));
X insider = (*u.ushops && inside_shop(u.ux, u.uy) &&
X *in_rooms(x, y, SHOPBASE) == *u.ushops);
X
X /* a box gets a chance of breaking open here */
X if(Is_box(kickobj)) {
X boolean otrp = kickobj->otrapped;
X struct obj *otmp2, *probj = (struct obj *) 0, *temp;
X long loss = 0L;
X
X if(range < 2) pline("THUD!");
X
X for(otmp = kickobj->cobj; otmp; otmp = otmp2) {
X otmp2 = otmp->nobj;
X if (objects[otmp->otyp].oc_material == GLASS
X && !rn2(3)) {
X You("hear a muffled shatter.");
X if(costly) loss += stolen_value(otmp, x, y,
X (boolean)shkp->mpeaceful, TRUE);
X if (otmp->quan > 1L)
X useup(otmp);
X else {
X temp = otmp;
X if (otmp == kickobj->cobj) {
X kickobj->cobj = otmp->nobj;
X otmp = (struct obj *) 0;
X } else {
X probj->nobj = otmp->nobj;
X otmp = probj;
X }
X obfree(temp, (struct obj *) 0);
X }
X }
X probj = otmp;
X }
X if(costly && loss) {
X if(!insider) {
X You("caused %ld zorkmids worth of damage!", loss);
X make_angry_shk(shkp, x, y);
X } else
X You("owe %s %ld zorkmids for objects destroyed.",
X mon_nam(shkp), loss);
X }
X
X if (kickobj->olocked) {
X if (!rn2(5) || (martial() && !rn2(2))) {
X You("break open the lock!");
X kickobj->olocked = 0;
X kickobj->obroken = 1;
X if (otrp) (void) chest_trap(kickobj, LEG, FALSE);
X return(1);
X }
X } else {
X if (!rn2(3) || (martial() && !rn2(2))) {
X pline("The lid slams open, then falls shut.");
X if (otrp) (void) chest_trap(kickobj, LEG, FALSE);
X return(1);
X }
X }
X if(range < 2) return(1);
X /* else let it fall through to the next cases... */
X }
X
X /* fragile objects should not be kicked */
X if (breaks(kickobj, FALSE)) return(1);
X
X /* potions get a chance of breaking here */
X if(kickobj->oclass == POTION_CLASS) {
X if(rn2(2)) {
X You("smash %s %s!",
X kickobj->quan == 1L ? "the" : "a", xname(kickobj));
X potionbreathe(kickobj);
X if(costly) {
X long loss = stolen_value(kickobj, kickobj->ox,
X kickobj->oy, (boolean)shkp->mpeaceful, TRUE);
X if(loss) {
X if(insider)
X You("owe %ld zorkmids for objects destroyed.",
X loss);
X else {
X You("caused %ld zorkmids worth of damage!", loss);
X make_angry_shk(shkp, kickobj->ox,
X kickobj->oy);
X }
X }
X }
X useupf(kickobj);
X return(1);
X }
X }
X
X if(IS_ROCK(levl[x][y].typ)) {
X if ((!martial() && rn2(20) > ACURR(A_DEX))
X#ifdef POLYSELF
X || IS_ROCK(levl[u.ux][u.uy].typ)
X#endif
X ) {
X if (Blind) pline("It doesn't come loose.");
X else pline("%s do%sn't come loose.",
X The(distant_name(kickobj, xname)),
X (kickobj->quan == 1L) ? "es" : "");
X return(!rn2(3) || martial());
X }
X if (Blind) pline("It comes loose.");
X else pline("%s come%s loose.",
X The(distant_name(kickobj, xname)),
X (kickobj->quan == 1L) ? "s" : "");
X remove_object(kickobj);
X newsym(x, y);
X if (costly && (!costly_spot(u.ux, u.uy)
X || !index(u.urooms, *in_rooms(x, y, SHOPBASE))))
X addtobill(kickobj, FALSE, FALSE, FALSE);
X if(!flooreffects(kickobj,u.ux,u.uy,"fall")) {
X place_object(kickobj, u.ux, u.uy);
X stackobj(kickobj);
X newsym(u.ux, u.uy);
X }
X return(1);
X }
X
X isgold = (kickobj->otyp == GOLD_PIECE);
X
X /* too heavy to move. range is calculated as potential distance from
X * player, so range == 2 means the object may move up to one square
X * from its current position
X */
X if(range < 2 || (isgold && kickobj->quan > 300L)) {
X if(!Is_box(kickobj)) pline("Thump!");
X return(!rn2(3) || martial());
X }
X
X if (kickobj->quan > 1L && !isgold) (void) splitobj(kickobj, 1L);
X
X freeobj(kickobj);
X newsym(x, y);
X mon = bhit(u.dx, u.dy, range, KICKED_WEAPON,
X (int (*)()) 0, (int (*)()) 0, kickobj);
X
X /* a flag to "drop" the object to the next level */
X shipit = (!mon && down_gate(bhitpos.x, bhitpos.y) != -1);
X
X if(mon) {
X notonhead = (mon->mx != bhitpos.x || mon->my != bhitpos.y);
X /* awake monster if sleeping */
X wakeup(mon);
X if(isgold ? ghitm(mon, kickobj) : /* caught? */
X thitmonst(mon, kickobj)) /* hit? */
X return(1);
X }
X if(costly &&
X (!costly_spot(bhitpos.x,bhitpos.y) || shipit ||
X *in_rooms(bhitpos.x, bhitpos.y, 0) != *in_rooms(x, y, 0))) {
X
X if(shipit && ship_object(kickobj, bhitpos.x, bhitpos.y, costly))
X return(1);
X
X if(isgold)
X costly_gold(x, y, kickobj->quan);
X else if(costly_spot(u.ux, u.uy) &&
X index(u.urooms, *in_rooms(x, y, 0)))
X addtobill(kickobj, FALSE, FALSE, FALSE);
X else (void)stolen_value(kickobj, x, y, FALSE, FALSE);
X }
X
X if(shipit && ship_object(kickobj, bhitpos.x, bhitpos.y, costly))
X return(1);
X if(flooreffects(kickobj,bhitpos.x,bhitpos.y,"fall")) return(1);
X kickobj->nobj = fobj;
X fobj = kickobj;
X place_object(kickobj, bhitpos.x, bhitpos.y);
X stackobj(kickobj);
X newsym(kickobj->ox, kickobj->oy);
X return(1);
X}
X
Xstatic char *
Xkickstr()
X{
X static char NEARDATA buf[BUFSZ];
X
X if (kickobj) Sprintf(buf, "kicking %s", doname(kickobj));
X else {
X Strcpy(buf, "kicking ");
X if (IS_STWALL(maploc->typ)) Strcat(buf, "a wall");
X else if (IS_ROCK(maploc->typ)) Strcat(buf, "a rock");
X else if (IS_THRONE(maploc->typ)) Strcat(buf, "a throne");
X#ifdef SINKS
X else if (IS_SINK(maploc->typ)) Strcat(buf, "a sink");
X#endif
X else if (IS_ALTAR(maploc->typ)) Strcat(buf, "an altar");
X else if (IS_DRAWBRIDGE(maploc->typ)) Strcat(buf, "the drawbridge");
X else {
X switch (maploc->typ) {
X case STAIRS:
X Strcat(buf, "the stairs");
X break;
X case LADDER:
X Strcat(buf, "a ladder");
X break;
X default:
X Strcat(buf, "something wierd");
X break;
X }
X }
X }
X return buf;
X}
X
Xint
Xdokick()
X{
X register int x, y;
X register int avrg_attrib = (ACURRSTR+ACURR(A_DEX)+ACURR(A_CON))/3;
X
X#ifdef POLYSELF
X if(nolimbs(uasmon)) {
X You("have no legs to kick with.");
X return(0);
X }
X if(verysmall(uasmon)) {
X You("are too small to do any kicking.");
X return(0);
X }
X#endif
X if(Wounded_legs) {
X Your("%s %s in no shape for kicking.",
X ((Wounded_legs & BOTH_SIDES)==BOTH_SIDES)
X ? (const char *)makeplural(body_part(LEG)) : body_part(LEG),
X ((Wounded_legs & BOTH_SIDES)==BOTH_SIDES) ? "are" : "is");
X return(0);
X }
X
X if(near_capacity() > SLT_ENCUMBER) {
X Your("load is too heavy to balance yourself for a kick.");
X return(0);
X }
X
X if(u.uinwater && !rn2(2)) {
X Your("slow motion kick doesn't hit anything.");
X return(0);
X }
X
X if(u.utrap) {
X switch (u.utraptype) {
X case TT_PIT:
X pline("There's nothing to kick down here.");
X case TT_WEB:
X case TT_BEARTRAP:
X You("can't move your %s!", body_part(LEG));
X }
X return(0);
X }
X
X if(!getdir(NULL)) return(0);
X if(!u.dx && !u.dy) return(0);
X
X x = u.ux + u.dx;
X y = u.uy + u.dy;
X
X if(u.uswallow) {
X switch(rn2(3)) {
X case 0: You("can't move your %s!", body_part(LEG));
X break;
X case 1: if (is_animal(u.ustuck->data)) {
X pline("%s burps loudly.", Monnam(u.ustuck));
X break;
X }
X default: Your("feeble kick has no effect."); break;
X }
X return(1);
X }
X
X wake_nearby();
X u_wipe_engr(2);
X
X maploc = &levl[x][y];
X
X /* The next four tests should stay in */
X /* their present order: monsters, objects, */
X /* non-doors, doors. */
X
X if(MON_AT(x, y)) {
X kick_monster(x, y);
X if((Is_airlevel(&u.uz) || Levitation) && flags.move) {
X int range;
X struct monst *mon;
X
X mon = m_at(x,y);
X range = (3*(int)mon->data->cwt) /
X ((int)uasmon->cwt + (weight_cap() + inv_weight()));
X if(range < 1) range = 1;
X hurtle(-u.dx, -u.dy, range);
X }
X return(1);
X }
X
X kickobj = (struct obj *)0;
X if (OBJ_AT(x, y) &&
X (!Levitation || Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)
X || sobj_at(BOULDER,x,y))) {
X if(kick_object(x, y)) {
X if(Is_airlevel(&u.uz))
X hurtle(-u.dx, -u.dy, 1); /* assume it's light */
X return(1);
X }
X goto ouch;
X }
X
X if(!IS_DOOR(maploc->typ)) {
X if(maploc->typ == SDOOR) {
X if(!Levitation && rn2(30) < avrg_attrib) {
X pline("Crash! You kick open a secret door!");
X exercise(A_DEX, TRUE);
X maploc->typ = DOOR;
X if(maploc->doormask & D_TRAPPED) {
X b_trapped("door");
X maploc->doormask = D_NODOOR;
X } else
X maploc->doormask = D_ISOPEN;
X if (Blind)
X feel_location(x,y); /* we know its gone */
X else
X newsym(x,y);
X unblock_point(x,y); /* vision */
X return(1);
X } else goto ouch;
X }
X if(maploc->typ == SCORR) {
X if(!Levitation && rn2(30) < avrg_attrib) {
X pline("Crash! You kick open a secret passage!");
X exercise(A_DEX, TRUE);
X maploc->typ = CORR;
X if (Blind)
X feel_location(x,y); /* we known its gone */
X else
X newsym(x,y);
X unblock_point(x,y); /* vision */
X return(1);
X } else goto ouch;
X }
X if(IS_THRONE(maploc->typ)) {
X register int i;
X if(Levitation) goto dumb;
X if((Luck < 0 || maploc->doormask) && !rn2(3)) {
X maploc->typ = ROOM;
X maploc->doormask = 0; /* don't leave loose ends.. */
X mkgold((long)rnd(200), x, y);
X if (Blind)
X pline("CRASH! You destroy it.");
X else {
X pline("CRASH! You destroy the throne.");
X newsym(x, y);
X }
X exercise(A_DEX, TRUE);
X return(1);
X } else if(Luck > 0 && !rn2(3) && !maploc->looted) {
X mkgold((long) rn1(201, 300), x, y);
X i = Luck + 1;
X if(i > 6) i = 6;
X while(i--) (void) mkobj_at(GEM_CLASS, x, y, TRUE);
X if (Blind)
X You("kick something loose!");
X else {
X You("kick loose some ornamental coins and gems!");
X newsym(x, y);
X }
X /* prevent endless milking */
X maploc->looted = T_LOOTED;
X return(1);
X } else if (!rn2(4)) {
X if(dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz)) {
X fall_through(FALSE);
X return(1);
X } else goto ouch;
X }
X goto ouch;
X }
X if(IS_ALTAR(maploc->typ)) {
X if(Levitation) goto dumb;
X You("kick %s.",(Blind ? "something" : "the altar"));
X if(!rn2(3)) goto ouch;
X altar_wrath(x, y);
X exercise(A_DEX, TRUE);
X return(1);
X }
X#ifdef SINKS
X if(IS_SINK(maploc->typ)) {
X if(Levitation) goto dumb;
X if(rn2(5)) {
X if(flags.soundok)
X pline("Klunk! The pipes vibrate noisily.");
X else pline("Klunk!");
X exercise(A_DEX, TRUE);
X return(1);
X } else if(!(maploc->looted & S_LPUDDING) && !rn2(3) &&
X !(mons[PM_BLACK_PUDDING].geno &
X (G_GENOD | G_EXTINCT))) {
X if (Blind)
X You("hear a gushing sound.");
X else
X pline("A %s ooze gushes up from the drain!",
X Hallucination ? hcolor() : Black);
X (void) makemon(&mons[PM_BLACK_PUDDING], x, y);
X exercise(A_DEX, TRUE);
X newsym(x,y);
X maploc->looted |= S_LPUDDING;
X return(1);
X } else if(!(maploc->looted & S_LDWASHER) && !rn2(3) &&
X# ifndef POLYSELF
X poly_gender() != 2 &&
X# endif
X !(mons[poly_gender() == 1 ?
X PM_INCUBUS : PM_SUCCUBUS].geno &
X (G_GENOD | G_EXTINCT))) {
X /* can't resist... */
X pline("%s returns!", (Blind ? "Something" :
X "The dish washer"));
X if (makemon(&mons[poly_gender() == 1 ?
X PM_INCUBUS : PM_SUCCUBUS], x, y)) newsym(x,y);
X maploc->looted |= S_LDWASHER;
X exercise(A_DEX, TRUE);
X return(1);
X } else if(!rn2(3)) {
X pline("Flupp! %s.", (Blind ?
X "You hear a sloshing sound" :
X "Muddy waste pops up from the drain"));
X if(!(maploc->looted & S_LRING)) { /* once per sink */
X if (!Blind)
X You("see a ring shining in its midst.");
X (void) mkobj_at(RING_CLASS, x, y, TRUE);
X newsym(x, y);
X exercise(A_DEX, TRUE);
X exercise(A_WIS, TRUE); /* a discovery! */
X maploc->looted |= S_LRING;
X }
X return(1);
X }
X goto ouch;
X }
X#endif
X if (maploc->typ == STAIRS || maploc->typ == LADDER ||
X IS_STWALL(maploc->typ)) {
X if(!IS_STWALL(maploc->typ) && maploc->ladder == LA_DOWN)
X goto dumb;
Xouch:
X pline("Ouch! That hurts!");
X exercise(A_DEX, FALSE);
X exercise(A_STR, FALSE);
X if (Blind) feel_location(x,y); /* we know we hit it */
X if(!rn2(3)) set_wounded_legs(RIGHT_SIDE, 5 + rnd(5));
X losehp(rnd(ACURR(A_CON) > 15 ? 3 : 5), kickstr(),
X KILLED_BY);
X if(Is_airlevel(&u.uz) || Levitation)
X hurtle(-u.dx, -u.dy, rn1(2,4)); /* assume it's heavy */
X return(1);
X }
X if (is_drawbridge_wall(x,y) >= 0) {
X pline("The drawbridge is unaffected.");
X if(Levitation)
X hurtle(-u.dx, -u.dy, rn1(2,4)); /* it's heavy */
X return(1);
X }
X goto dumb;
X }
X
X if(maploc->doormask == D_ISOPEN ||
X maploc->doormask == D_BROKEN ||
X maploc->doormask == D_NODOOR) {
Xdumb:
X exercise(A_DEX, FALSE);
X if (martial() || ACURR(A_DEX) >= 16 || rn2(3)) {
X You("kick at empty space.");
X } else {
X pline("Dumb move! You strain a muscle.");
X exercise(A_STR, FALSE);
X set_wounded_legs(RIGHT_SIDE, 5 + rnd(5));
X }
X if(Is_airlevel(&u.uz) || Levitation)
X hurtle(-u.dx, -u.dy, rn2(2));
X return(0);
X }
X
X /* not enough leverage to kick open doors while levitating */
X if(Levitation) goto ouch;
X
X exercise(A_DEX, TRUE);
X /* door is known to be CLOSED or LOCKED */
X if(rnl(35) < avrg_attrib + (!martial() ? 0 : ACURR(A_DEX))) {
X /* break the door */
X if(maploc->doormask & D_TRAPPED) {
X pline("As you kick the door, it explodes!");
X exercise(A_STR, FALSE);
X b_trapped("door");
X maploc->doormask = D_NODOOR;
X } else if(ACURR(A_STR) > 18 && !rn2(5) &&
X !*in_rooms(x, y, SHOPBASE)) {
X pline("As you kick the door, it shatters to pieces!");
X exercise(A_STR, TRUE);
X maploc->doormask = D_NODOOR;
X } else {
X pline("As you kick the door, it crashes open!");
X exercise(A_STR, TRUE);
X if(*in_rooms(x, y, SHOPBASE)) {
X add_damage(x, y, 400L);
X pay_for_damage("break");
X }
X maploc->doormask = D_BROKEN;
X }
X if (Blind)
X feel_location(x,y); /* we know we broke it */
X else
X newsym(x,y);
X unblock_point(x,y); /* vision */
X } else {
X if (Blind) feel_location(x,y); /* we know we hit it */
X exercise(A_STR, TRUE);
X pline("WHAMMM!!!");
X }
X return(1);
X}
X
Xstatic const char *
Xgate_str(gate)
Xregister xchar gate;
X{
X const char *optr;
X
X switch(gate) {
X case 0:
X case 4: optr = "through the trap door."; break;
X case 1:
X case 3: optr = "down the stairs."; break;
X case 2: optr = "down the ladder."; break;
X default: optr = "down out of sight."; break;
X }
X return(optr);
X}
X
Xstatic
Xvoid
Xdrop_to(cc, loc)
Xcoord *cc;
Xregister xchar loc;
X{
X switch(loc) {
X case 0: if(In_endgame(&u.uz) || (Is_botlevel(&u.uz) &&
X !Is_stronghold(&u.uz))) {
X cc->y = 0;
X return;
X }
X if(Is_stronghold(&u.uz)) {
X cc->x = valley_level.dnum;
X cc->y = valley_level.dlevel;
X break;
X } /* else fall to the next cases */
X case 1:
X case 2:
X cc->x = u.uz.dnum;
X cc->y = u.uz.dlevel + 1;
X break;
X case 3:
X cc->x = sstairs.tolev.dnum;
X cc->y = sstairs.tolev.dlevel;
X break;
X default:
X cc->y = 0;
X }
X}
X
Xvoid
Ximpact_drop(missile, x, y, dlev)
Xregister struct obj *missile;
Xregister xchar x, y, dlev;
X{
X xchar toloc;
X register struct obj *obj, *obj2;
X register struct monst *shkp;
X long oct, dct, price, debit, robbed;
X boolean angry, costly, isrock;
X coord cc;
X
X if(!OBJ_AT(x, y)) return;
X
X toloc = down_gate(x, y);
X drop_to(&cc, toloc);
X if (!cc.y) return;
X
X if (dlev) {
X /* send objects next to player falling through trap door.
X * checked in obj_delivery().
X */
X toloc = 4;
X cc.y = dlev;
X }
X
X costly = costly_spot(x, y);
X price = debit = robbed = 0L;
X angry = FALSE;
X shkp = (struct monst *) 0;
X /* if 'costly', we must keep a record of ESHK(shkp) before
X * it undergoes changes through the calls to stolen_value.
X * the angry bit must be reset, if needed, in this fn, since
X * stolen_value is called under the 'silent' flag to avoid
X * unsavory pline repetitions.
X */
X if(costly) {
X if((shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) !=
X (struct monst *)0) {
X debit = ESHK(shkp)->debit;
X robbed = ESHK(shkp)->robbed;
X angry = !shkp->mpeaceful;
X }
X }
X
X isrock = (missile && missile->otyp == ROCK);
X oct = dct = 0L;
X for(obj = level.objects[x][y]; obj; obj = obj2) {
X obj2 = obj->nexthere;
X if(obj == missile) continue;
X /* number of objects in the pile */
X oct += obj->quan;
X /* boulders can fall too, but rarely & never due to rocks */
X if((isrock && obj->otyp == BOULDER) ||
X rn2(obj->otyp == BOULDER ? 30 : 3)) continue;
X freeobj(obj);
X
X if(costly) {
X price += stolen_value(obj, x, y,
X (costly_spot(u.ux, u.uy) &&
X index(u.urooms, *in_rooms(x, y, SHOPBASE))),
X TRUE);
X /* set obj->no_charge to 0 */
X if(Is_container(obj))
X picked_container(obj); /* does the right thing */
X if(obj->otyp != GOLD_PIECE)
X obj->no_charge = 0;
X }
X obj->nobj = migrating_objs;
X migrating_objs = obj;
X
X obj->ox = cc.x;
X obj->oy = cc.y;
X obj->owornmask = (long)toloc;
X
X /* number of fallen objects */
X dct += obj->quan;
X }
X
X if (dct) { /* at least one object fell */
X const char *what = (dct == 1L ? "object falls" : "objects fall");
X if (missile)
X pline("From the impact, %sother %s.",
X dct == oct ? "the " : dct == 1L ? "an" : "", what);
X else
X pline("%s adjacent %s %s",
X oct == dct ? (dct > 1L ? "All the" : "The") :
X (dct == 1L ? "One of the" : "Some of the"),
X what, gate_str(toloc));
X }
X
X if(costly && shkp && price) {
X if(ESHK(shkp)->robbed > robbed) {
X You("removed %ld zorkmids worth of goods!", price);
X if(cansee(shkp->mx, shkp->my)) {
X if(ESHK(shkp)->customer[0] == 0)
X (void) strncpy(ESHK(shkp)->customer,
X plname, PL_NSIZ);
X if(angry)
X pline("%s is infuriated!", Monnam(shkp));
X else pline("\"%s, you are a thief!\"", plname);
X } else You("hear a scream, \"Thief!\"");
X hot_pursuit(shkp);
X (void) angry_guards(FALSE);
X return;
X }
X if(ESHK(shkp)->debit > debit)
X You("owe %s %ld zorkmids for goods lost.",
X Monnam(shkp),
X (ESHK(shkp)->debit - debit));
X }
X
X}
X
X/* NOTE: ship_object assumes otmp was FREED from fobj or invent.
X * <x,y> is the point of drop. otmp is _not_ an <x,y> resident:
X * otmp is either a kicked, dropped, or thrown object.
X */
Xboolean
Xship_object(otmp, x, y, shop_floor_obj)
Xregister xchar x, y;
Xregister struct obj *otmp;
Xregister boolean shop_floor_obj;
X{
X register xchar ox, oy;
X register xchar toloc = down_gate(x, y);
X /* toloc -- destination location: */
X /* 0: rnd loc,
X * 1: <,
X * 2: < ladder,
X * 3: sstairs up
X * 4: near player (trapdoor)
X */
X coord cc;
X /* objects always fall down ladder, a chance of stay otherwise */
X register boolean nodrop = (toloc != 2 && rn2(3));
X register boolean unpaid, container, impact = FALSE;
X int n = 0;
X
X if(!otmp) return(FALSE);
X if(toloc == -1) return(FALSE);
X
X drop_to(&cc, toloc);
X if(!cc.y) return(FALSE);
X
X container = Is_container(otmp);
X
X unpaid = (otmp->unpaid || (container && count_unpaid(otmp->cobj)));
X
X if(OBJ_AT(x, y)) {
X register struct obj *obj;
X
X for(obj = level.objects[x][y]; obj; obj = obj->nexthere)
X if(obj != otmp) n++;
X if(n) impact = TRUE;
X }
X
X otransit_msg(otmp, toloc, nodrop, n);
X
X if(nodrop) {
X otmp->nobj = fobj;
X fobj = otmp;
X place_object(otmp, x, y);
X stackobj(otmp);
X newsym(otmp->ox, otmp->oy);
X if(impact) goto chain_reaction;
X else return(TRUE);
X }
X
X if(unpaid || shop_floor_obj) {
X if(unpaid) {
X subfrombill(otmp, shop_keeper(*u.ushops));
X (void)stolen_value(otmp, u.ux, u.uy, TRUE, FALSE);
X } else {
X ox = otmp->ox;
X oy = otmp->oy;
X (void)stolen_value(otmp, ox, oy,
X (costly_spot(u.ux, u.uy) &&
X index(u.urooms, *in_rooms(ox, oy, SHOPBASE))),
X FALSE);
X }
X /* set otmp->no_charge to 0 */
X if(container)
X picked_container(otmp); /* happens to do the right thing */
X if(otmp->otyp != GOLD_PIECE)
X otmp->no_charge = 0;
X }
X
X otmp->nobj = migrating_objs;
X migrating_objs = otmp;
X
X otmp->ox = cc.x;
X otmp->oy = cc.y;
X otmp->owornmask = (long)toloc;
Xchain_reaction:
X if(impact) {
X /* the objs impacted may be in a shop other than
X * the one in which the hero is located. another
X * check for a shk is made in impact_drop. it is, e.g.,
X * possible to kick/throw an object belonging to one
X * shop into another shop through a gap in the wall,
X * and cause objects belonging to the other shop to
X * fall down a trapdoor--thereby getting two shopkeepers
X * angry at the hero in one shot.
X */
X impact_drop(otmp, x, y, 0);
X newsym(x,y);
X }
X return(TRUE);
X}
X
Xvoid
Xobj_delivery()
X{
X register struct obj *otmp, *otmp0 = (struct obj *)0, *otmp2;
X
X for(otmp = migrating_objs; otmp; otmp = otmp2) {
X
X otmp2 = otmp->nobj;
X
X if(otmp->ox == u.uz.dnum && otmp->oy == u.uz.dlevel) {
X if(otmp == migrating_objs)
X migrating_objs = otmp->nobj;
X else
X otmp0->nobj = otmp->nobj;
X otmp->nobj = fobj;
X fobj = otmp;
X
X switch((xchar)otmp->owornmask) {
X xchar *xlocale, *ylocale;
X
X case 1: xlocale = &xupstair; ylocale = &yupstair;
X goto common;
X case 2: xlocale = &xupladder; ylocale = &yupladder;
X goto common;
X case 3: xlocale = &sstairs.sx; ylocale = &sstairs.sy;
X goto common;
X case 4: { /* hero falls down trapdoor with objects */
X xchar nx, ny;
X int cnt = 0;
X
X do {
X nx = u.ux - 1 + rn2(3);
X ny = u.uy - 1 + rn2(3);
X } while((nx < 1 || nx > COLNO-2 ||
X ny < 1 || ny > ROWNO-2 ||
X is_pool(nx,ny) || is_lava(nx,ny) ||
X !ACCESSIBLE(levl[nx][ny].typ) ||
X closed_door(nx, ny)
X ) && cnt++ <= 50);
X
X if(cnt >= 50) goto scatter; /* safety */
X xlocale = &nx;
X ylocale = &ny;
X }
Xcommon:
X if (*xlocale && *ylocale) {
X place_object(otmp, *xlocale, *ylocale);
X stackobj(otmp);
X break;
X } /* else fall through */
X default:
Xscatter:
X rloco(otmp);
X break;
X }
X otmp->owornmask = 0L;
X } else
X otmp0 = otmp;
X }
X}
X
Xstatic void
Xotransit_msg(otmp, loc, nodrop, num)
Xregister struct obj *otmp;
Xregister xchar loc;
Xregister boolean nodrop;
Xint num;
X{
X char obuf[BUFSZ];
X
X Sprintf(obuf, "%s%s",
X (otmp->otyp == CORPSE &&
X type_is_pname(&mons[otmp->corpsenm])) ? "" : "The ",
X xname(otmp));
X
X if(num) { /* means: other objects are impacted */
X Sprintf(eos(obuf), " hit%s %s object%s",
X otmp->quan == 1L ? "s" : "",
X num == 1 ? "another" : "other",
X num > 1 ? "s" : "");
X if(nodrop)
X Sprintf(eos(obuf), " and stop%s.",
X otmp->quan == 1L ? "s" : "");
X else
X Sprintf(eos(obuf), " and fall%s %s",
X otmp->quan == 1L ? "s" : "", gate_str(loc));
X pline(obuf);
X } else if(!nodrop)
X pline("%s fall%s %s", obuf,
X otmp->quan == 1L ? "s" : "",
X gate_str(loc));
X}
X
Xxchar
Xdown_gate(x, y)
Xxchar x, y;
X{
X register struct trap *ttmp = t_at(x, y);
X
X if(ttmp && ttmp->ttyp == TRAPDOOR && ttmp->tseen) return 0;
X if(xdnstair == x && ydnstair == y) return 1;
X if(xdnladder == x && ydnladder == y) return 2;
X if(sstairs.sx == x && sstairs.sy == y && !sstairs.up) return 3;
X return -1;
X}
X
X/*dokick.c*/
END_OF_FILE
if test 32287 -ne `wc -c <'src/dokick.c'`; then
echo shar: \"'src/dokick.c'\" unpacked with wrong size!
fi
# end of 'src/dokick.c'
fi
if test -f 'sys/amiga/splitter/split.doc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'sys/amiga/splitter/split.doc'\"
else
echo shar: Extracting \"'sys/amiga/splitter/split.doc'\" \(1323 characters\)
sed "s/^X//" >'sys/amiga/splitter/split.doc' <<'END_OF_FILE'
X Splitter [split.doc 93/01/08]
X
XUsage:
X splitter [-Cc_prototype] [-Dd_prototype] [-ddir_prototype] binary
X
XDefault prototypes:
X d: %n.dir
X C: %n.c%C
X D: %n.d%D
X
XPrototypes:
X %n base file name
X %C current code file #
X %D current data file #
X
XCreates:
X binary.dir directions file
X binary.d00 data files
X binary.d01 ...
X binary.c00 code files
X binary.c01 ...
X
XFormat of the directions file (subject to change):
X Cbinary.c00
X Cbinary.c01
X Cbinary.c02
X Dbinary.d00
X Dbinary.d01
XThe above entries may be edited to reflect the location of the various files
Xif it is necessary for them to be moved by the user. All C entries must
Xpreceed all D entries.
X
XMaximum output file size is 800K (819200 bytes) - this leaves just enough
Xspace on an empty floppy for a small icon.
X
XCode file contents:
XThe first code file contains:
X the (modified) HUNK_HEADER from the original binary
X (followed by)
XAll code files contain:
X HUNK_CODE's from the original binary
X
XData file contents:
X HUNK_BSS's from the original binary
X HUNK_DATA's from the original binary
X
XCOMPILING
X [SASC5]
X lc -L splitter.c arg.c
X
XBUGS
X The present system for generating multiple files is a hack -
X multi.[ch] should be upgraded instead.
X
X Many optimizations for minimizing the size of the output file
X could/should/will be added.
X
X Not tested with SASC 6.0 yet.
END_OF_FILE
if test 1323 -ne `wc -c <'sys/amiga/splitter/split.doc'`; then
echo shar: \"'sys/amiga/splitter/split.doc'\" unpacked with wrong size!
fi
# end of 'sys/amiga/splitter/split.doc'
fi
if test -f 'win/tty/termcap.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'win/tty/termcap.c'\"
else
echo shar: Extracting \"'win/tty/termcap.c'\" \(19701 characters\)
sed "s/^X//" >'win/tty/termcap.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)termcap.c 3.1 92/11/15 */
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed. See license for details. */
X
X#include "hack.h"
X#include "wintty.h"
X
X#include "termcap.h"
X
X
X#ifdef MICROPORT_286_BUG
X#define Tgetstr(key) (tgetstr(key,tbuf))
X#else
X#define Tgetstr(key) (tgetstr(key,&tbufptr))
X#endif /* MICROPORT_286_BUG **/
X
Xvoid FDECL(cmov, (int, int));
Xvoid FDECL(nocmov, (int, int));
X#ifdef TEXTCOLOR
X# ifdef TERMLIB
X# ifdef OVLB
X# ifndef TOS
Xstatic void FDECL(analyze_seq, (char *, int *, int *));
X# endif
Xstatic void NDECL(init_hilite);
X# endif /* OVLB */
X# endif
X#endif
X
X#ifdef OVLB
X /* (see termcap.h) -- CM, ND, CD, HI,HE, US,UE, ul_hack */
Xstruct tc_lcl_data tc_lcl_data = { 0, 0, 0, 0,0, 0,0, FALSE };
X#endif /* OVLB */
X
XSTATIC_VAR char *HO, *CL, *CE, *UP, *XD, *BC, *SO, *SE, *TI, *TE;
XSTATIC_VAR char *VS, *VE;
X#if 0
XSTATIC_VAR char *MR, *ME;
XSTATIC_VAR char *MB, *MH;
XSTATIC_VAR char *MD; /* may already be in use below */
X#endif
X#ifdef TERMLIB
X# ifdef TEXTCOLOR
XSTATIC_VAR char *MD;
X# endif
XSTATIC_VAR int SG;
X#ifdef OVLB
XSTATIC_OVL char PC = '\0';
X#else /* OVLB */
XSTATIC_DCL char PC;
X#endif /* OVLB */
XSTATIC_VAR char tbuf[512];
X#endif
X
X#ifdef TEXTCOLOR
X# ifdef TOS
Xconst char *hilites[MAXCOLORS]; /* terminal escapes for the various colors */
X# else
Xchar NEARDATA *hilites[MAXCOLORS]; /* terminal escapes for the various colors */
X# endif
X#endif
X
X#ifdef OVLB
Xstatic char *KS = NULL, *KE = NULL; /* keypad sequences */
Xstatic char nullstr[] = "";
X#endif /* OVLB */
X
X#ifndef TERMLIB
XSTATIC_VAR char tgotobuf[20];
X# ifdef TOS
X#define tgoto(fmt, x, y) (Sprintf(tgotobuf, fmt, y+' ', x+' '), tgotobuf)
X# else
X#define tgoto(fmt, x, y) (Sprintf(tgotobuf, fmt, y+1, x+1), tgotobuf)
X# endif
X#endif /* TERMLIB */
X
X#ifdef OVLB
X
Xvoid
Xtty_startup(wid, hgt)
X int *wid, *hgt;
X{
X#ifdef TERMLIB
X register const char *term;
X register char *tptr;
X char *tbufptr, *pc;
X#endif
X register int i;
X
X#ifdef TERMLIB
X# ifdef VMS
X if (!(term = verify_termcap()))
X# endif
X term = getenv("TERM");
X#endif
X
X#ifdef TERMLIB
X if(!term)
X#endif
X#if defined(TOS) && defined(__GNUC__) && defined(TERMLIB)
X term = "builtin"; /* library has a default */
X#else
X# ifdef ANSI_DEFAULT
X# ifdef TOS
X {
X CO = 80; LI = 25;
X TI = VS = VE = TE = nullstr;
X HO = "\033H";
X CL = "\033E"; /* the VT52 termcap */
X CE = "\033K";
X UP = "\033A";
X CM = "\033Y%c%c"; /* used with function tgoto() */
X ND = "\033C";
X XD = "\033B";
X BC = "\033D";
X SO = "\033p";
X SE = "\033q";
X /* HI and HE will be updated in init_hilite if we're using color */
X HI = "\033p";
X HE = "\033q";
X }
X# else /* TOS */
X {
X# ifdef MICRO
X get_scr_size();
X# ifdef CLIPPING
X if(CO < COLNO || LI < ROWNO+3)
X setclipped();
X# endif
X# endif
X HO = "\033[H";
X CL = "\033[2J"; /* the ANSI termcap */
X/* CD = "\033[J"; */
X CE = "\033[K";
X# ifndef TERMLIB
X CM = "\033[%d;%dH";
X# else
X CM = "\033[%i%d;%dH";
X# endif
X UP = "\033[A";
X ND = "\033[C";
X XD = "\033[B";
X# ifdef MICRO /* backspaces are non-destructive */
X BC = "\b";
X# else
X BC = "\033[D";
X# endif
X HI = SO = "\033[1m";
X US = "\033[4m";
X# if 0
X MR = "\033[7m";
X ME = "\033[0m";
X# endif
X TI = HE = SE = UE = "\033[0m";
X /* strictly, SE should be 2, and UE should be 24,
X but we can't trust all ANSI emulators to be
X that complete. -3. */
X# ifndef MICRO
X AS = "\016";
X AE = "\017";
X# endif
X TE = VS = VE = nullstr;
X# ifdef TEXTCOLOR
X for (i = 0; i < MAXCOLORS / 2; i++)
X if (i != BLACK) {
X hilites[i|BRIGHT] = (char *) alloc(sizeof("\033[1;3%dm"));
X Sprintf(hilites[i|BRIGHT], "\033[1;3%dm", i);
X if (i != GRAY)
X# ifdef MICRO
X if (i == BLUE) hilites[BLUE] = hilites[BLUE|BRIGHT];
X else
X# endif
X {
X hilites[i] = (char *) alloc(sizeof("\033[0;3%dm"));
X Sprintf(hilites[i], "\033[0;3%dm", i);
X }
X }
X# endif
X *wid = CO;
X *hgt = LI;
X return;
X }
X# endif /* TOS */
X# else
X error("Can't get TERM.");
X# endif /* ANSI_DEFAULT */
X#endif /* __GNUC__ && TOS && TERMCAP */
X#ifdef TERMLIB
X tptr = (char *) alloc(1024);
X
X tbufptr = tbuf;
X if(!strncmp(term, "5620", 4))
X flags.null = FALSE; /* this should be a termcap flag */
X if(tgetent(tptr, term) < 1)
X error("Unknown terminal type: %s.", term);
X if ((pc = Tgetstr("pc")) != 0)
X PC = *pc;
X
X if(!(BC = Tgetstr("le"))) /* both termcap and terminfo use le */
X# ifdef TERMINFO
X error("Terminal must backspace.");
X# else
X if(!(BC = Tgetstr("bc"))) { /* termcap also uses bc/bs */
X# if !defined(MINIMAL_TERM)
X if(!tgetflag("bs"))
X error("Terminal must backspace.");
X# endif
X BC = tbufptr;
X tbufptr += 2;
X *BC = '\b';
X }
X# endif
X
X# ifdef MINIMAL_TERM
X HO = NULL;
X# else
X HO = Tgetstr("ho");
X# endif
X /*
X * LI and CO are set in ioctl.c via a TIOCGWINSZ if available. If
X * the kernel has values for either we should use them rather than
X * the values from TERMCAP ...
X */
X# ifndef MICRO
X if (!CO) CO = tgetnum("co");
X if (!LI) LI = tgetnum("li");
X# else
X# if defined(TOS) && defined(__GNUC__)
X if (!strcmp(term, "builtin"))
X get_scr_size();
X else {
X# endif
X CO = tgetnum("co");
X LI = tgetnum("li");
X if (!LI || !CO) /* if we don't override it */
X get_scr_size();
X# if defined(TOS) && defined(__GNUC__)
X }
X# endif
X# endif
X# ifdef CLIPPING
X if(CO < COLNO || LI < ROWNO+3)
X setclipped();
X# endif
X if(!(CL = Tgetstr("cl")))
X error("Hack needs CL.");
X ND = Tgetstr("nd");
X if(tgetflag("os"))
X error("Hack can't have OS.");
X if(tgetflag("ul"))
X ul_hack = TRUE;
X CE = Tgetstr("ce");
X UP = Tgetstr("up");
X /* It seems that xd is no longer supported, and we should use
X a linefeed instead; unfortunately this requires resetting
X CRMOD, and many output routines will have to be modified
X slightly. Let's leave that till the next release. */
X XD = Tgetstr("xd");
X/* not: XD = Tgetstr("do"); */
X if(!(CM = Tgetstr("cm"))) {
X if(!UP && !HO)
X error("Hack needs CM or UP or HO.");
X tty_raw_print("Playing hack on terminals without cm is suspect...");
X tty_wait_synch();
X }
X SO = Tgetstr("so");
X SE = Tgetstr("se");
X US = Tgetstr("us");
X UE = Tgetstr("ue");
X SG = tgetnum("sg"); /* -1: not fnd; else # of spaces left by so */
X if(!SO || !SE || (SG > 0)) SO = SE = US = UE = nullstr;
X TI = Tgetstr("ti");
X TE = Tgetstr("te");
X VS = VE = nullstr;
X# ifdef TERMINFO
X VS = Tgetstr("eA"); /* enable graphics */
X# endif
X KS = Tgetstr("ks"); /* keypad start (special mode) */
X KE = Tgetstr("ke"); /* keypad end (ordinary mode [ie, digits]) */
X# if 0
X MR = Tgetstr("mr"); /* reverse */
X MB = Tgetstr("mb"); /* blink */
X MD = Tgetstr("md"); /* boldface */
X MH = Tgetstr("mh"); /* dim */
X ME = Tgetstr("me");
X# endif
X
X /* Get rid of padding numbers for HI and HE. Hope they
X * aren't really needed!!! HI and HE are ouputted to the
X * pager as a string - so how can you send it NULLS???
X * -jsb
X */
X HI = (char *) alloc((unsigned)(strlen(SO)+1));
X HE = (char *) alloc((unsigned)(strlen(SE)+1));
X i = 0;
X while (digit(SO[i])) i++;
X Strcpy(HI, &SO[i]);
X i = 0;
X while (digit(SE[i])) i++;
X Strcpy(HE, &SE[i]);
X AS = Tgetstr("as");
X AE = Tgetstr("ae");
X CD = Tgetstr("cd");
X# ifdef TEXTCOLOR
X MD = Tgetstr("md");
X# endif
X if(tbufptr-tbuf > sizeof(tbuf)) error("TERMCAP entry too big...\n");
X free((genericptr_t)tptr);
X# ifdef TEXTCOLOR
X# if defined(TOS) && defined(__GNUC__)
X if (!strcmp(term, "builtin") || !strcmp(term, "tw52")) {
X init_hilite();
X }
X# else
X init_hilite();
X# endif
X# endif
X#endif /* TERMLIB */
X *wid = CO;
X *hgt = LI;
X}
X
Xvoid
Xtty_number_pad(state)
Xint state;
X{
X switch (state) {
X case -1: /* activate keypad mode (escape sequences) */
X if (KS && *KS) xputs(KS);
X break;
X case 1: /* activate numeric mode for keypad (digits) */
X if (KE && *KE) xputs(KE);
X break;
X case 0: /* don't need to do anything--leave terminal as-is */
X default:
X break;
X }
X}
X
X#ifdef TERMLIB
Xextern void NDECL((*decgraphics_mode_callback)); /* defined in drawing.c */
Xstatic void NDECL(tty_decgraphics_termcap_fixup);
X
X/*
X We call this routine whenever DECgraphics mode is enabled, even if it
X has been previously set, in case the user manages to reset the fonts.
X The actual termcap fixup only needs to be done once, but we can't
X call xputs() from the option setting or graphics assigning routines,
X so this is a convenient hook.
X */
Xstatic void
Xtty_decgraphics_termcap_fixup()
X{
X static char ctrlN[] = "\016";
X static char ctrlO[] = "\017";
X static char appMode[] = "\033=";
X static char numMode[] = "\033>";
X
X /* these values are missing from some termcaps */
X if (!AS) AS = ctrlN; /* ^N (shift-out [graphics font]) */
X if (!AE) AE = ctrlO; /* ^O (shift-in [regular font]) */
X if (!KS) KS = appMode; /* ESC= (application keypad mode) */
X if (!KE) KE = numMode; /* ESC> (numeric keypad mode) */
X /*
X * Select the line-drawing character set as the alternate font.
X * Do not select NA ASCII as the primary font since people may
X * reasonably be using the UK character set.
X */
X if (flags.DECgraphics) xputs("\033)0");
X}
X#endif
X
Xvoid
Xtty_start_screen()
X{
X xputs(TI);
X xputs(VS);
X#ifdef TERMLIB
X if (flags.DECgraphics) tty_decgraphics_termcap_fixup();
X /* set up callback in case option is not set yet but toggled later */
X decgraphics_mode_callback = tty_decgraphics_termcap_fixup;
X#endif
X if (flags.num_pad) tty_number_pad(1); /* make keypad send digits */
X}
X
Xvoid
Xtty_end_screen()
X{
X clear_screen();
X xputs(VE);
X xputs(TE);
X}
X
X/* Cursor movements */
X
X#endif /* OVLB */
X
X#ifdef OVL0
X/* Note to OVLx tinkerers. The placement of this overlay controls the location
X of the function xputc(). This function is not currently in trampoli.[ch]
X files for what is deemed to be performance reasons. If this define is moved
X and or xputc() is taken out of the ROOT overlay, then action must be taken
X in trampoli.[ch]. */
X
Xvoid
Xnocmov(x, y)
Xint x,y;
X{
X if ((int) ttyDisplay->cury > y) {
X if(UP) {
X while ((int) ttyDisplay->cury > y) { /* Go up. */
X xputs(UP);
X ttyDisplay->cury--;
X }
X } else if(CM) {
X cmov(x, y);
X } else if(HO) {
X home();
X tty_curs(BASE_WINDOW, x+1, y);
X } /* else impossible("..."); */
X } else if ((int) ttyDisplay->cury < y) {
X if(XD) {
X while((int) ttyDisplay->cury < y) {
X xputs(XD);
X ttyDisplay->cury++;
X }
X } else if(CM) {
X cmov(x, y);
X } else {
X while((int) ttyDisplay->cury < y) {
X xputc('\n');
X ttyDisplay->curx = 0;
X ttyDisplay->cury++;
X }
X }
X }
X if ((int) ttyDisplay->curx < x) { /* Go to the right. */
X if(!ND) cmov(x, y); else /* bah */
X /* should instead print what is there already */
X while ((int) ttyDisplay->curx < x) {
X xputs(ND);
X ttyDisplay->curx++;
X }
X } else if ((int) ttyDisplay->curx > x) {
X while ((int) ttyDisplay->curx > x) { /* Go to the left. */
X xputs(BC);
X ttyDisplay->curx--;
X }
X }
X}
X
Xvoid
Xcmov(x, y)
Xregister int x, y;
X{
X xputs(tgoto(CM, x, y));
X ttyDisplay->cury = y;
X ttyDisplay->curx = x;
X}
X
X/* See note at OVLx ifdef above. xputc() is a special function. */
Xvoid
Xxputc(c)
X#if defined(apollo)
Xint c;
X#else
Xchar c;
X#endif
X{
X (void) putchar(c);
X}
X
Xvoid
Xxputs(s)
Xconst char *s;
X{
X# ifndef TERMLIB
X (void) fputs(s, stdout);
X# else
X# if defined(NHSTDC) || defined(ULTRIX_PROTO)
X tputs(s, 1, (int (*)())xputc);
X# else
X tputs(s, 1, xputc);
X# endif
X# endif
X}
X
Xvoid
Xcl_end()
X{
X if(CE)
X xputs(CE);
X else { /* no-CE fix - free after Harold Rynes */
X /* this looks terrible, especially on a slow terminal
X but is better than nothing */
X register int cx = ttyDisplay->curx+1;
X
X while(cx < CO) {
X xputc(' ');
X cx++;
X }
X tty_curs(BASE_WINDOW, (int)ttyDisplay->curx+1,
X (int)ttyDisplay->cury);
X }
X}
X
X#endif /* OVL0 */
X#ifdef OVLB
X
Xvoid
Xclear_screen()
X{
X /* note: if CL is null, then termcap initialization failed,
X so don't attempt screen-oriented I/O during final cleanup.
X */
X if (CL) {
X xputs(CL);
X home();
X }
X}
X
X#endif /* OVLB */
X#ifdef OVL0
X
Xvoid
Xhome()
X{
X if(HO)
X xputs(HO);
X else if(CM)
X xputs(tgoto(CM, 0, 0));
X else
X tty_curs(BASE_WINDOW, 1, 0); /* using UP ... */
X ttyDisplay->curx = ttyDisplay->cury = 0;
X}
X
Xvoid
Xstandoutbeg()
X{
X if(SO) xputs(SO);
X}
X
Xvoid
Xstandoutend()
X{
X if(SE) xputs(SE);
X}
X
X#if 0 /* if you need one of these, uncomment it (here and in extern.h) */
Xvoid
Xrevbeg()
X{
X if(MR) xputs(MR);
X}
X
Xvoid
Xboldbeg()
X{
X if(MD) xputs(MD);
X}
X
Xvoid
Xblinkbeg()
X{
X if(MB) xputs(MB);
X}
X
Xvoid
Xdimbeg()
X/* not in most termcap entries */
X{
X if(MH) xputs(MH);
X}
X
Xvoid
Xm_end()
X{
X if(ME) xputs(ME);
X}
X#endif
X
X#endif /* OVL0 */
X#ifdef OVLB
X
Xvoid
Xbacksp()
X{
X xputs(BC);
X}
X
Xvoid
Xtty_nhbell()
X{
X if (flags.silent) return;
X (void) putchar('\007'); /* curx does not change */
X (void) fflush(stdout);
X}
X
X#endif /* OVLB */
X#ifdef OVL0
X
X#ifdef ASCIIGRAPH
Xvoid
Xgraph_on() {
X if (AS) xputs(AS);
X}
X
Xvoid
Xgraph_off() {
X if (AE) xputs(AE);
X}
X#endif
X
X#endif /* OVL0 */
X#ifdef OVL1
X
X#if !defined(MICRO)
X# ifdef VMS
Xstatic const short tmspc10[] = { /* from termcap */
X 0, 2000, 1333, 909, 743, 666, 333, 166, 83, 55, 50, 41, 27, 20, 13, 10,
X 5
X};
X# else
Xstatic const short tmspc10[] = { /* from termcap */
X 0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5
X};
X# endif
X#endif
X
Xvoid
Xtty_delay_output()
X{
X /* delay 50 ms - could also use a 'nap'-system call */
X /* BUG: if the padding character is visible, as it is on the 5620
X then this looks terrible. */
X#if defined(MICRO)
X /* simulate the delay with "cursor here" */
X register int i;
X for (i = 0; i < 3; i++) {
X cmov(ttyDisplay->curx, ttyDisplay->cury);
X (void) fflush(stdout);
X }
X#else /* MICRO */
X if(flags.null)
X# ifdef TERMINFO
X /* cbosgd!cbcephus!pds for SYS V R2 */
X# ifdef NHSTDC
X tputs("$<50>", 1, (int (*)())xputc);
X# else
X tputs("$<50>", 1, xputc);
X# endif
X# else
X# if defined(NHSTDC) || defined(ULTRIX_PROTO)
X tputs("50", 1, (int (*)())xputc);
X# else
X tputs("50", 1, xputc);
X# endif
X# endif
X
X else if(ospeed > 0 && ospeed < SIZE(tmspc10)) if(CM) {
X /* delay by sending cm(here) an appropriate number of times */
X register int cmlen = strlen(tgoto(CM, ttyDisplay->curx, ttyDisplay->cury));
X register int i = 500 + tmspc10[ospeed]/2;
X
X while(i > 0) {
X cmov((int)ttyDisplay->curx, (int)ttyDisplay->cury);
X i -= cmlen*tmspc10[ospeed];
X }
X }
X#endif /* MICRO */
X}
X
X#endif /* OVL1 */
X#ifdef OVLB
X
Xvoid
Xcl_eos() /* free after Robert Viduya */
X{ /* must only be called with curx = 1 */
X
X if(CD)
X xputs(CD);
X else {
X register int cy = ttyDisplay->cury+1;
X while(cy <= LI-2) {
X cl_end();
X xputc('\n');
X cy++;
X }
X cl_end();
X tty_curs(BASE_WINDOW, (int)ttyDisplay->curx+1,
X (int)ttyDisplay->cury);
X }
X}
X
X#if defined(TEXTCOLOR) && defined(TERMLIB)
X# if defined(UNIX) && defined(TERMINFO)
X/*
X * Sets up color highlighting, using terminfo(4) escape sequences (highlight
X * code found in print.c). It is assumed that the background color is black.
X */
X/* terminfo indexes for the basic colors it guarantees */
X#define COLOR_BLACK 1 /* fake out to avoid black on black */
X#define COLOR_BLUE 1
X#define COLOR_GREEN 2
X#define COLOR_CYAN 3
X#define COLOR_RED 4
X#define COLOR_MAGENTA 5
X#define COLOR_YELLOW 6
X#define COLOR_WHITE 7
X
X/* map ANSI RGB to terminfo BGR */
Xconst int ti_map[8] = {
X COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW,
X COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE };
X
Xstatic void
Xinit_hilite()
X{
X register int c;
X char *setf, *scratch;
X extern char *tparm();
X
X for (c = 0; c < SIZE(hilites); c++)
X hilites[c] = HI;
X hilites[GRAY] = hilites[NO_COLOR] = NULL;
X
X if (tgetnum("Co") < 8 || (setf = tgetstr("Sf", (char **)0)) == NULL)
X return;
X
X for (c = 0; c < MAXCOLORS / 2; c++) {
X scratch = tparm(setf, ti_map[c]);
X if (c != GRAY) {
X hilites[c] = (char *) alloc(strlen(scratch) + 1);
X Strcpy(hilites[c], scratch);
X }
X if (c != BLACK) {
X hilites[c|BRIGHT] = (char*) alloc(strlen(scratch)+strlen(MD)+1);
X Strcpy(hilites[c|BRIGHT], MD);
X Strcat(hilites[c|BRIGHT], scratch);
X }
X
X }
X}
X
X# else /* UNIX && TERMINFO */
X
X# ifndef TOS
X/* find the foreground and background colors set by HI or HE */
Xstatic void
Xanalyze_seq (str, fg, bg)
Xchar *str;
Xint *fg, *bg;
X{
X register int c, code;
X int len;
X
X# ifdef MICRO
X *fg = GRAY; *bg = BLACK;
X# else
X *fg = *bg = NO_COLOR;
X# endif
X
X if (str[0] != '\033' || str[1] != '[' ||
X str[len = strlen(str) - 1] != 'm' || len < 3)
X return;
X
X c = 2;
X while (c < len) {
X if ((code = atoi(&str[c])) == 0) { /* reset */
X /* this also catches errors */
X# ifdef MICRO
X *fg = GRAY; *bg = BLACK;
X# else
X *fg = *bg = NO_COLOR;
X# endif
X } else if (code == 1) { /* bold */
X *fg |= BRIGHT;
X# if 0
X /* I doubt we'll ever resort to using blinking characters,
X unless we want a pulsing glow for something. But, in case
X we do... - 3. */
X } else if (code == 5) { /* blinking */
X *fg |= BLINK;
X } else if (code == 25) { /* stop blinking */
X *fg &= ~BLINK;
X# endif
X } else if (code == 7 || code == 27) { /* reverse */
X code = *fg & ~BRIGHT;
X *fg = *bg | (*fg & BRIGHT);
X *bg = code;
X } else if (code >= 30 && code <= 37) { /* hi_foreground RGB */
X *fg = code - 30;
X } else if (code >= 40 && code <= 47) { /* hi_background RGB */
X *bg = code - 40;
X }
X while (digit(str[++c]));
X c++;
X }
X}
X# endif
X
X/*
X * Sets up highlighting sequences, using ANSI escape sequences (highlight code
X * found in print.c). The HI and HE sequences (usually from SO) is scanned to
X * find foreground and background colors.
X */
X
Xstatic void
Xinit_hilite()
X{
X register int c;
X# ifdef TOS
X extern unsigned long tos_numcolors; /* in tos.c */
X static const char NOCOL[] = "\033b0", COLHE[] = "\033q\033b0";
X
X HI = "\033p";
X# else
X int backg, foreg, hi_backg, hi_foreg;
X# endif
X
X for (c = 0; c < SIZE(hilites); c++)
X hilites[c] = HI;
X hilites[GRAY] = hilites[NO_COLOR] = NULL;
X
X# ifdef TOS
X if (tos_numcolors <= 2) {
X return;
X }
X/* Under TOS, the "bright" and "dim" colors are reversed. Moreover,
X * on the Falcon the dim colors are *really* dim; so we make most
X * of the colors the bright versions, with a few exceptions where
X * the dim ones look OK.
X */
X hilites[0] = NOCOL;
X for (c = 1; c < SIZE(hilites); c++) {
X hilites[c] = (char *) alloc(sizeof("\033b0"));
X if (tos_numcolors > 4)
X Sprintf(hilites[c], "\033b%c", (c&~BRIGHT)+'0');
X else
X Strcpy(hilites[c], HI);
X }
X
X if (tos_numcolors == 4) {
X TI = "\033b0\033c3\033E\033e";
X TE = "\033b3\033c0\033J";
X HE = COLHE;
X hilites[GREEN] = hilites[GREEN|BRIGHT] = "\033b2";
X hilites[RED] = hilites[RED|BRIGHT] = "\033b1";
X } else {
X sprintf(hilites[BROWN], "\033b%c", (BROWN^BRIGHT)+'0');
X sprintf(hilites[GREEN], "\033b%c", (GREEN^BRIGHT)+'0');
X
X TI = "\033b0\033c\017\033E\033e";
X TE = "\033b\017\033c0\033J";
X HE = COLHE;
X hilites[WHITE] = hilites[BLACK] = NOCOL;
X hilites[NO_COLOR] = hilites[GRAY];
X }
X
X# else /* TOS */
X analyze_seq(HI, &hi_foreg, &hi_backg);
X analyze_seq(HE, &foreg, &backg);
X
X for (c = 0; c < SIZE(hilites); c++)
X /* avoid invisibility */
X if ((backg & ~BRIGHT) != c) {
X# ifdef MICRO
X if (c == BLUE) continue;
X# endif
X if (c == foreg)
X hilites[c] = NULL;
X else if (c != hi_foreg && backg != hi_backg) {
X hilites[c] = (char *) alloc(sizeof("\033[%d;3%d;4%dm"));
X Sprintf(hilites[c], "\033[%d", !!(c & BRIGHT));
X if ((c | BRIGHT) != (foreg | BRIGHT))
X Sprintf(eos(hilites[c]), ";3%d", c & ~BRIGHT);
X if (backg != BLACK)
X Sprintf(eos(hilites[c]), ";4%d", backg & ~BRIGHT);
X Strcat(hilites[c], "m");
X }
X }
X
X# ifdef MICRO
X /* brighten low-visibility colors */
X hilites[BLUE] = hilites[BLUE|BRIGHT];
X# endif
X# endif /* TOS */
X}
X# endif /* UNIX */
X#endif /* TEXTCOLOR */
X
X#endif /* OVLB */
X
X/*termcap.c*/
END_OF_FILE
if test 19701 -ne `wc -c <'win/tty/termcap.c'`; then
echo shar: \"'win/tty/termcap.c'\" unpacked with wrong size!
fi
# end of 'win/tty/termcap.c'
fi
echo shar: End of archive 59 \(of 108\).
cp /dev/null ark59isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 \
101 102 103 104 105 106 107 108 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 108 archives.
echo "Now execute 'rebuild.sh'"
rm -f ark10[0-8]isdone ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0