home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / games / volume16 / nethack31 / part59 < prev    next >
Internet Message Format  |  1993-02-04  |  59KB

  1. Path: uunet!news.tek.com!master!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v16i067:  nethack31 - display oriented dungeons & dragons (Ver. 3.1), Part59/108
  5. Message-ID: <4370@master.CNA.TEK.COM>
  6. Date: 1 Feb 93 19:45:40 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 2250
  9. Approved: billr@saab.CNA.TEK.COM
  10. Xref: uunet comp.sources.games:1617
  11.  
  12. Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
  13. Posting-number: Volume 16, Issue 67
  14. Archive-name: nethack31/Part59
  15. Supersedes: nethack3p9: Volume 10, Issue 46-102
  16. Environment: Amiga, Atari, Mac, MS-DOS, OS2, Unix, VMS, X11
  17.  
  18.  
  19.  
  20. #! /bin/sh
  21. # This is a shell archive.  Remove anything before this line, then unpack
  22. # it by saving it into a file and typing "sh file".  To overwrite existing
  23. # files, type "sh file -c".  You can also feed this as standard input via
  24. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  25. # will see the following message at the end:
  26. #        "End of archive 59 (of 108)."
  27. # Contents:  src/dokick.c sys/amiga/splitter/split.doc
  28. #   win/tty/termcap.c
  29. # Wrapped by billr@saab on Wed Jan 27 16:09:10 1993
  30. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  31. if test -f 'src/dokick.c' -a "${1}" != "-c" ; then 
  32.   echo shar: Will not clobber existing file \"'src/dokick.c'\"
  33. else
  34. echo shar: Extracting \"'src/dokick.c'\" \(32287 characters\)
  35. sed "s/^X//" >'src/dokick.c' <<'END_OF_FILE'
  36. X/*    SCCS Id: @(#)dokick.c    3.1    92/10/06    */
  37. X/* Copyright (c) Izchak Miller, Mike Stephenson, Steve Linhart, 1989. */
  38. X/* NetHack may be freely redistributed.  See license for details. */
  39. X
  40. X#include    "hack.h"
  41. X#include    "eshk.h"
  42. X
  43. X#ifndef POLYSELF
  44. X# define martial()    (pl_character[0] == 'S' || pl_character[0] == 'P')
  45. X#else
  46. X# define is_bigfoot(x)    ((x) == &mons[PM_SASQUATCH])
  47. X# define martial()    (pl_character[0] == 'S' || pl_character[0] == 'P' \
  48. X             || is_bigfoot(uasmon))
  49. X#endif
  50. X
  51. Xstatic struct rm NEARDATA *maploc;
  52. X
  53. Xextern boolean notonhead;    /* for long worms */
  54. X
  55. Xstatic void FDECL(kickdmg, (struct monst *, BOOLEAN_P));
  56. Xstatic void FDECL(kick_monster, (XCHAR_P, XCHAR_P));
  57. Xstatic int FDECL(kick_object, (XCHAR_P, XCHAR_P));
  58. Xstatic char *NDECL(kickstr);
  59. Xstatic void FDECL(otransit_msg, (struct obj *, XCHAR_P, BOOLEAN_P, int));
  60. Xstatic const char *FDECL(gate_str, (XCHAR_P));
  61. Xstatic void FDECL(drop_to, (coord *, XCHAR_P));
  62. X
  63. Xstatic struct obj NEARDATA *kickobj;
  64. X
  65. X#define IS_SHOP(x)    (rooms[x].rtype >= SHOPBASE)
  66. X
  67. Xstatic void
  68. Xkickdmg(mon, clumsy)
  69. Xregister struct monst *mon;
  70. Xregister boolean clumsy;
  71. X{
  72. X    register int mdx, mdy;
  73. X    register int dmg = ( ACURRSTR + ACURR(A_DEX) + ACURR(A_CON) )/ 15;
  74. X
  75. X    /* excessive wt affects dex, so it affects dmg */
  76. X    if(clumsy) dmg = dmg/2;
  77. X
  78. X    /* kicking a dragon or an elephant will not harm it */
  79. X    if(thick_skinned(mon->data)) dmg = 0;
  80. X
  81. X    /* a good kick exercises your dex */
  82. X    exercise(A_DEX, TRUE);
  83. X
  84. X    /* squeeze some guilt feelings... */
  85. X    if(mon->mtame) {
  86. X#ifdef SOUNDS
  87. X        if (rn2(10)) yelp(mon);
  88. X        else growl(mon); /* give them a moment's worry */
  89. X#endif
  90. X        mon->mtame--;
  91. X        if(!mon->mtame) newsym(mon->mx, mon->my);
  92. X        mon->mflee = mon->mtame ? 1 : 0;
  93. X#ifdef HISX
  94. X        mon->mfleetim = mon->mfleetim + (dmg ? rnd(dmg) : 1);
  95. X#else
  96. X        mon->mfleetim += (dmg ? rnd(dmg) : 1);
  97. X#endif
  98. X    }
  99. X
  100. X    if (dmg)
  101. X        mon->mhp -= (!martial() ? rnd(dmg) :
  102. X            rnd(dmg)+rnd(ACURR(A_DEX)/2));
  103. X    if(mon->mhp < 1) {
  104. X        (void) passive(mon, TRUE, 0, TRUE);
  105. X        killed(mon);
  106. X        return;
  107. X    }
  108. X    if(martial() && !bigmonst(mon->data) && !rn2(3) && mon->mcanmove) {
  109. X        /* see if the monster has a place to move into */
  110. X        mdx = mon->mx + u.dx;
  111. X        mdy = mon->my + u.dy;
  112. X        if(goodpos(mdx, mdy, mon, mon->data)) {
  113. X            pline("%s reels from the blow.", Monnam(mon));
  114. X            remove_monster(mon->mx, mon->my);
  115. X            place_monster(mon, mdx, mdy);
  116. X            newsym(mon->mx, mon->my);
  117. X            set_apparxy(mon);
  118. X        }
  119. X    }
  120. X    (void) passive(mon, FALSE, 1, TRUE);
  121. X
  122. X/*    it is unchivalrous to attack the defenseless or from behind */
  123. X    if (pl_character[0] == 'K' &&
  124. X        u.ualign.type == A_LAWFUL && u.ualign.record > -10 &&
  125. X        (!mon->mcanmove || mon->msleep || mon->mflee))
  126. X        adjalign(-1);
  127. X
  128. X}
  129. X
  130. Xstatic void
  131. Xkick_monster(x, y)
  132. Xregister xchar x, y;
  133. X{
  134. X    register boolean clumsy = FALSE;
  135. X    register struct monst *mon = m_at(x, y);
  136. X    register int i, j;
  137. X
  138. X    bhitpos.x = x;
  139. X    bhitpos.y = y;
  140. X    if(special_case(mon)) return;
  141. X    setmangry(mon);
  142. X#ifdef POLYSELF
  143. X    /* Kick attacks by kicking monsters are normal attacks, not special.
  144. X     * If you have >1 kick attack, you get all of them.
  145. X     */
  146. X    if (attacktype(uasmon, AT_KICK)) {
  147. X        schar tmp = find_roll_to_hit(mon);
  148. X        for(i=0; i<NATTK; i++) {
  149. X        if (uasmon->mattk[i].aatyp == AT_KICK && multi >= 0) {
  150. X            /* check multi; maybe they had 2 kicks and the first */
  151. X            /* was a kick against a floating eye */
  152. X            if (tmp > rnd(20)) {
  153. X            int sum;
  154. X
  155. X            You("kick %s.", mon_nam(mon));
  156. X            sum = damageum(mon, &(uasmon->mattk[i]));
  157. X            if (sum == 2)
  158. X                (void)passive(mon, 1, 0, TRUE);
  159. X            else (void)passive(mon, sum, 1, TRUE);
  160. X            } else {
  161. X            missum(mon, &(uasmon->mattk[i]));
  162. X            (void)passive(mon, 0, 1, TRUE);
  163. X            }
  164. X        }
  165. X        }
  166. X        return;
  167. X    }
  168. X#endif
  169. X
  170. X    /* no need to check POLYSELF since only ghosts, which you can't turn */
  171. X    /* into, are noncorporeal */
  172. X    if(noncorporeal(mon->data)) {
  173. X        Your("kick passes through!");
  174. X        return;
  175. X    }
  176. X
  177. X    if(Levitation && !rn2(3) && verysmall(mon->data) &&
  178. X       !is_flyer(mon->data)) {
  179. X        pline("Floating in the air, you miss wildly!");
  180. X        exercise(A_DEX, FALSE);
  181. X        (void) passive(mon, FALSE, 1, TRUE);
  182. X        return;
  183. X    }
  184. X
  185. X    i = -inv_weight();
  186. X    j = weight_cap();
  187. X
  188. X    if(i < (j*3)/10) {
  189. X        if(!rn2((i < j/10) ? 2 : (i < j/5) ? 3 : 4)) {
  190. X            if(martial() && !rn2(2)) goto doit;
  191. X            Your("clumsy kick does no damage.");
  192. X            (void) passive(mon, FALSE, 1, TRUE);
  193. X            return;
  194. X        }
  195. X        if(i < j/10) clumsy = TRUE;
  196. X        else if(!rn2((i < j/5) ? 2 : 3)) clumsy = TRUE;
  197. X    }
  198. X
  199. X    if(Fumbling) clumsy = TRUE;
  200. X
  201. X    else if(uarm && objects[uarm->otyp].oc_bulky && ACURR(A_DEX) < rnd(25))
  202. X        clumsy = TRUE;
  203. Xdoit:
  204. X    You("kick %s.", mon_nam(mon));
  205. X    if(!rn2(clumsy ? 3 : 4) && (clumsy || !bigmonst(mon->data)) &&
  206. X       mon->mcansee && !mon->mtrapped && !thick_skinned(mon->data) &&
  207. X       mon->data->mlet != S_EEL && haseyes(mon->data) && mon->mcanmove &&
  208. X       !mon->mstun && !mon->mconf && !mon->msleep &&
  209. X       mon->data->mmove >= 12) {
  210. X        if(!nohands(mon->data) && !rn2(martial() ? 5 : 3)) {
  211. X            pline("%s blocks your %skick.", Monnam(mon),
  212. X                clumsy ? "clumsy " : "");
  213. X            (void) passive(mon, FALSE, 1, TRUE);
  214. X            return;
  215. X        } else {
  216. X            mnexto(mon);
  217. X            if(mon->mx != x || mon->my != y) {
  218. X            pline("%s %s, %s evading your %skick.", Monnam(mon),
  219. X                (can_teleport(mon->data) ? "teleports" :
  220. X                 is_floater(mon->data) ? "floats" :
  221. X                 is_flyer(mon->data) ? "flutters" :
  222. X                 nolimbs(mon->data) ? "slides" :
  223. X                 "jumps"),
  224. X                clumsy ? "easily" : "nimbly",
  225. X                clumsy ? "clumsy " : "");
  226. X            (void) passive(mon, FALSE, 1, TRUE);
  227. X            return;
  228. X            }
  229. X        }
  230. X    }
  231. X    kickdmg(mon, clumsy);
  232. X}
  233. X
  234. X/*
  235. X *  Return TRUE if caught (the gold taken care of), FALSE otherwise.
  236. X *  The gold object is *not* attached to the fobj chain!
  237. X */
  238. Xboolean
  239. Xghitm(mtmp, gold)
  240. Xregister struct monst *mtmp;
  241. Xregister struct obj *gold;
  242. X{
  243. X    if(!likes_gold(mtmp->data) && !mtmp->isshk && !mtmp->ispriest
  244. X#ifdef ARMY
  245. X        && !is_mercenary(mtmp->data)
  246. X#endif
  247. X        ) {
  248. X        wakeup(mtmp);
  249. X    } else if (!mtmp->mcanmove) {
  250. X        /* too light to do real damage */
  251. X        if (canseemon(mtmp))
  252. X            pline("The gold hits %s.", mon_nam(mtmp));
  253. X    } else {
  254. X        mtmp->msleep = 0;
  255. X        mtmp->meating = 0;
  256. X        if(!rn2(4)) setmangry(mtmp); /* not always pleasing */
  257. X
  258. X        /* greedy monsters catch gold */
  259. X        if (cansee(mtmp->mx, mtmp->my))
  260. X            pline("%s catches the gold.", Monnam(mtmp));
  261. X        mtmp->mgold += gold->quan;
  262. X        if (mtmp->isshk) {
  263. X            long robbed = ESHK(mtmp)->robbed;
  264. X
  265. X            if (robbed) {
  266. X                robbed -= gold->quan;
  267. X                if (robbed < 0) robbed = 0;
  268. X                pline("The amount %scovers %s recent losses.",
  269. X                    !robbed ? "" : "partially ",
  270. X                    mtmp->female ? "her" : "his");
  271. X                ESHK(mtmp)->robbed = robbed;
  272. X                if(!robbed)
  273. X                    make_happy_shk(mtmp, FALSE);
  274. X            } else {
  275. X                if(mtmp->mpeaceful) {
  276. X                    ESHK(mtmp)->credit += gold->quan;
  277. X                    You("have %ld zorkmid%s in credit.",
  278. X                    ESHK(mtmp)->credit,
  279. X                    plur(ESHK(mtmp)->credit));
  280. X                } else verbalize("Thanks, scum!");
  281. X            }
  282. X        }
  283. X        else if(mtmp->ispriest) {
  284. X            if(mtmp->mpeaceful)
  285. X                verbalize("Thank you for your contribution.");
  286. X            else verbalize("Thanks, scum!");
  287. X        }
  288. X        else if(is_mercenary(mtmp->data)) {
  289. X            if(rn2(3)) {
  290. X            if(mtmp->data == &mons[PM_SOLDIER]) {
  291. X               if(gold->quan > 100 + (u.ugold + (u.ulevel*rn2(5)))
  292. X                        /ACURR(A_CHA))
  293. X                mtmp->mpeaceful = 1;
  294. X                }
  295. X            if(mtmp->data == &mons[PM_SERGEANT]) {
  296. X               if(gold->quan > 250 + (u.ugold + (u.ulevel*rn2(5)))
  297. X                        /ACURR(A_CHA))
  298. X                mtmp->mpeaceful = 1;
  299. X                }
  300. X            if(mtmp->data == &mons[PM_LIEUTENANT]) {
  301. X               if(gold->quan > 500 + (u.ugold + (u.ulevel*rn2(5)))
  302. X                        /ACURR(A_CHA))
  303. X                mtmp->mpeaceful = 1;
  304. X                }
  305. X            if(mtmp->data == &mons[PM_CAPTAIN]) {
  306. X               if(gold->quan > 750 + (u.ugold + (u.ulevel*rn2(5)))
  307. X                        /ACURR(A_CHA))
  308. X                mtmp->mpeaceful = 1;
  309. X                }
  310. X             }
  311. X             if(mtmp->mpeaceful)
  312. X                verbalize("That should do.  Now beat it!");
  313. X             else verbalize("That's not enough, coward!");
  314. X             }
  315. X
  316. X        dealloc_obj(gold);
  317. X        return(1);
  318. X    }
  319. X    return(0);
  320. X}
  321. X
  322. Xstatic int
  323. Xkick_object(x, y)
  324. Xxchar x, y;
  325. X{
  326. X    int range;
  327. X    register struct monst *mon, *shkp;
  328. X    register struct obj *otmp;
  329. X    struct trap *trap;
  330. X    boolean costly, insider, shipit;
  331. X    boolean isgold;
  332. X
  333. X    /* if a pile, the "top" object gets kicked */
  334. X    kickobj = level.objects[x][y];
  335. X
  336. X    /* kickobj should always be set due to conditions of call */
  337. X    if(!kickobj || kickobj->otyp == BOULDER
  338. X            || kickobj == uball || kickobj == uchain)
  339. X        return(0);
  340. X
  341. X    if((trap = t_at(x,y)) && trap->tseen) {
  342. X        if (((trap->ttyp == PIT || trap->ttyp == SPIKED_PIT)
  343. X#ifdef POLYSELF
  344. X            && !passes_walls(uasmon)
  345. X#endif
  346. X            ) || trap->ttyp == WEB) {
  347. X            You("can't kick something that's in a %s!",
  348. X                trap->ttyp == WEB ? "web" : "pit");
  349. X            return(1);
  350. X        }
  351. X    }
  352. X
  353. X    if(Fumbling && !rn2(3)) {
  354. X        Your("clumsy kick missed.");
  355. X        return(1);
  356. X    }
  357. X
  358. X    /* range < 2 means the object will not move.    */
  359. X    /* maybe dexterity should also figure here.     */
  360. X    range = (int)((ACURRSTR)/2 - kickobj->owt/40);
  361. X
  362. X    if(martial()) range += rnd(3);
  363. X
  364. X    /* Mjollnir is magically too heavy to kick */
  365. X    if(kickobj->oartifact == ART_MJOLLNIR) range = 1;
  366. X
  367. X    /* see if the object has a place to move into */
  368. X    if(!ZAP_POS(levl[x+u.dx][y+u.dy].typ) || closed_door(x+u.dx, y+u.dy))
  369. X        range = 1;
  370. X
  371. X    costly = ((shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) && 
  372. X                             costly_spot(x, y));
  373. X    insider = (*u.ushops && inside_shop(u.ux, u.uy) &&
  374. X                    *in_rooms(x, y, SHOPBASE) == *u.ushops);
  375. X
  376. X    /* a box gets a chance of breaking open here */
  377. X    if(Is_box(kickobj)) {
  378. X        boolean otrp = kickobj->otrapped;
  379. X        struct obj *otmp2, *probj = (struct obj *) 0, *temp;
  380. X        long loss = 0L;
  381. X
  382. X        if(range < 2) pline("THUD!");
  383. X
  384. X        for(otmp = kickobj->cobj; otmp; otmp = otmp2) {
  385. X            otmp2 = otmp->nobj;
  386. X            if (objects[otmp->otyp].oc_material == GLASS
  387. X                                && !rn2(3)) {
  388. X                You("hear a muffled shatter.");
  389. X                if(costly) loss += stolen_value(otmp, x, y, 
  390. X                        (boolean)shkp->mpeaceful, TRUE);
  391. X                if (otmp->quan > 1L)
  392. X                    useup(otmp);
  393. X                else {
  394. X                    temp = otmp;
  395. X                    if (otmp == kickobj->cobj) {
  396. X                        kickobj->cobj = otmp->nobj;
  397. X                        otmp = (struct obj *) 0;
  398. X                    } else {
  399. X                        probj->nobj = otmp->nobj;
  400. X                        otmp = probj;
  401. X                    }
  402. X                    obfree(temp, (struct obj *) 0);
  403. X                }
  404. X            }
  405. X            probj = otmp;
  406. X        }
  407. X        if(costly && loss) {
  408. X            if(!insider) {
  409. X                  You("caused %ld zorkmids worth of damage!", loss);
  410. X            make_angry_shk(shkp, x, y);
  411. X            } else
  412. X                You("owe %s %ld zorkmids for objects destroyed.",
  413. X                     mon_nam(shkp), loss);
  414. X        }
  415. X
  416. X        if (kickobj->olocked) {
  417. X            if (!rn2(5) || (martial() && !rn2(2))) {
  418. X            You("break open the lock!");
  419. X            kickobj->olocked = 0;
  420. X            kickobj->obroken = 1;
  421. X            if (otrp) (void) chest_trap(kickobj, LEG, FALSE);
  422. X            return(1);
  423. X            }
  424. X        } else {
  425. X            if (!rn2(3) || (martial() && !rn2(2))) {
  426. X            pline("The lid slams open, then falls shut.");
  427. X            if (otrp) (void) chest_trap(kickobj, LEG, FALSE);
  428. X            return(1);
  429. X            }
  430. X        }
  431. X        if(range < 2) return(1);
  432. X        /* else let it fall through to the next cases... */
  433. X    }
  434. X
  435. X    /* fragile objects should not be kicked */
  436. X    if (breaks(kickobj, FALSE)) return(1);
  437. X
  438. X    /* potions get a chance of breaking here */
  439. X    if(kickobj->oclass == POTION_CLASS) {
  440. X        if(rn2(2)) {
  441. X            You("smash %s %s!",
  442. X              kickobj->quan == 1L ? "the" : "a", xname(kickobj));
  443. X            potionbreathe(kickobj);
  444. X            if(costly) {
  445. X                long loss = stolen_value(kickobj, kickobj->ox,
  446. X                   kickobj->oy, (boolean)shkp->mpeaceful, TRUE);
  447. X            if(loss) {
  448. X                if(insider)
  449. X                  You("owe %ld zorkmids for objects destroyed.",
  450. X                                              loss);
  451. X                else {
  452. X                     You("caused %ld zorkmids worth of damage!", loss);
  453. X                      make_angry_shk(shkp, kickobj->ox, 
  454. X                                        kickobj->oy);
  455. X                }
  456. X            }
  457. X            }
  458. X            useupf(kickobj);
  459. X            return(1);
  460. X        }
  461. X    }
  462. X
  463. X    if(IS_ROCK(levl[x][y].typ)) {
  464. X        if ((!martial() && rn2(20) > ACURR(A_DEX))
  465. X#ifdef POLYSELF
  466. X                || IS_ROCK(levl[u.ux][u.uy].typ)
  467. X#endif
  468. X                                ) {
  469. X            if (Blind) pline("It doesn't come loose.");
  470. X            else pline("%s do%sn't come loose.",
  471. X                The(distant_name(kickobj, xname)),
  472. X                (kickobj->quan == 1L) ? "es" : "");
  473. X            return(!rn2(3) || martial());
  474. X        }
  475. X        if (Blind) pline("It comes loose.");
  476. X        else pline("%s come%s loose.",
  477. X               The(distant_name(kickobj, xname)),
  478. X               (kickobj->quan == 1L) ? "s" : "");
  479. X        remove_object(kickobj);
  480. X        newsym(x, y);
  481. X        if (costly && (!costly_spot(u.ux, u.uy)
  482. X                   || !index(u.urooms, *in_rooms(x, y, SHOPBASE))))
  483. X            addtobill(kickobj, FALSE, FALSE, FALSE);
  484. X        if(!flooreffects(kickobj,u.ux,u.uy,"fall")) {
  485. X            place_object(kickobj, u.ux, u.uy);
  486. X            stackobj(kickobj);
  487. X            newsym(u.ux, u.uy);
  488. X        }
  489. X        return(1);
  490. X    }
  491. X
  492. X    isgold = (kickobj->otyp == GOLD_PIECE);
  493. X
  494. X    /* too heavy to move.  range is calculated as potential distance from
  495. X     * player, so range == 2 means the object may move up to one square
  496. X     * from its current position
  497. X     */
  498. X    if(range < 2 || (isgold && kickobj->quan > 300L)) {
  499. X        if(!Is_box(kickobj)) pline("Thump!");
  500. X        return(!rn2(3) || martial());
  501. X    }
  502. X
  503. X    if (kickobj->quan > 1L && !isgold) (void) splitobj(kickobj, 1L);
  504. X
  505. X    freeobj(kickobj);
  506. X    newsym(x, y);
  507. X    mon = bhit(u.dx, u.dy, range, KICKED_WEAPON,
  508. X           (int (*)()) 0, (int (*)()) 0, kickobj);
  509. X
  510. X    /* a flag to "drop" the object to the next level */
  511. X    shipit = (!mon && down_gate(bhitpos.x, bhitpos.y) != -1);
  512. X
  513. X    if(mon) {
  514. X        notonhead = (mon->mx != bhitpos.x || mon->my != bhitpos.y);
  515. X        /* awake monster if sleeping */
  516. X        wakeup(mon);
  517. X        if(isgold ? ghitm(mon, kickobj) :    /* caught? */
  518. X           thitmonst(mon, kickobj))        /* hit? */
  519. X        return(1);
  520. X    }
  521. X    if(costly &&
  522. X       (!costly_spot(bhitpos.x,bhitpos.y) || shipit ||
  523. X        *in_rooms(bhitpos.x, bhitpos.y, 0) != *in_rooms(x, y, 0))) {
  524. X
  525. X        if(shipit && ship_object(kickobj, bhitpos.x, bhitpos.y, costly))
  526. X        return(1);
  527. X
  528. X        if(isgold)
  529. X        costly_gold(x, y, kickobj->quan);
  530. X        else if(costly_spot(u.ux, u.uy) &&
  531. X            index(u.urooms, *in_rooms(x, y, 0)))
  532. X        addtobill(kickobj, FALSE, FALSE, FALSE);
  533. X        else (void)stolen_value(kickobj, x, y, FALSE, FALSE);
  534. X    }
  535. X
  536. X    if(shipit && ship_object(kickobj, bhitpos.x, bhitpos.y, costly))
  537. X        return(1);
  538. X    if(flooreffects(kickobj,bhitpos.x,bhitpos.y,"fall")) return(1);
  539. X    kickobj->nobj = fobj;
  540. X    fobj = kickobj;
  541. X    place_object(kickobj, bhitpos.x, bhitpos.y);
  542. X    stackobj(kickobj);
  543. X    newsym(kickobj->ox, kickobj->oy);
  544. X    return(1);
  545. X}
  546. X
  547. Xstatic char *
  548. Xkickstr()
  549. X{
  550. X    static char NEARDATA buf[BUFSZ];
  551. X
  552. X    if (kickobj) Sprintf(buf, "kicking %s", doname(kickobj));
  553. X    else {
  554. X      Strcpy(buf, "kicking ");
  555. X      if (IS_STWALL(maploc->typ)) Strcat(buf, "a wall");
  556. X      else if (IS_ROCK(maploc->typ)) Strcat(buf, "a rock");
  557. X      else if (IS_THRONE(maploc->typ)) Strcat(buf, "a throne");
  558. X#ifdef SINKS
  559. X      else if (IS_SINK(maploc->typ)) Strcat(buf, "a sink");
  560. X#endif
  561. X      else if (IS_ALTAR(maploc->typ)) Strcat(buf, "an altar");
  562. X      else if (IS_DRAWBRIDGE(maploc->typ)) Strcat(buf, "the drawbridge");
  563. X      else {
  564. X        switch (maploc->typ) {
  565. X        case STAIRS:
  566. X            Strcat(buf, "the stairs");
  567. X            break;
  568. X        case LADDER:
  569. X            Strcat(buf, "a ladder");
  570. X            break;
  571. X        default:
  572. X            Strcat(buf, "something wierd");
  573. X            break;
  574. X        }
  575. X      }
  576. X    }
  577. X    return buf;
  578. X}
  579. X
  580. Xint
  581. Xdokick()
  582. X{
  583. X    register int x, y;
  584. X    register int avrg_attrib = (ACURRSTR+ACURR(A_DEX)+ACURR(A_CON))/3;
  585. X
  586. X#ifdef POLYSELF
  587. X    if(nolimbs(uasmon)) {
  588. X        You("have no legs to kick with.");
  589. X        return(0);
  590. X    }
  591. X    if(verysmall(uasmon)) {
  592. X        You("are too small to do any kicking.");
  593. X        return(0);
  594. X    }
  595. X#endif
  596. X    if(Wounded_legs) {
  597. X        Your("%s %s in no shape for kicking.",
  598. X              ((Wounded_legs & BOTH_SIDES)==BOTH_SIDES)
  599. X            ? (const char *)makeplural(body_part(LEG)) : body_part(LEG),
  600. X              ((Wounded_legs & BOTH_SIDES)==BOTH_SIDES) ? "are" : "is");
  601. X        return(0);
  602. X    }
  603. X
  604. X    if(near_capacity() > SLT_ENCUMBER) {
  605. X        Your("load is too heavy to balance yourself for a kick.");
  606. X        return(0);
  607. X    }
  608. X
  609. X    if(u.uinwater && !rn2(2)) {
  610. X        Your("slow motion kick doesn't hit anything.");
  611. X        return(0);
  612. X    }
  613. X
  614. X    if(u.utrap) {
  615. X        switch (u.utraptype) {
  616. X            case TT_PIT:
  617. X            pline("There's nothing to kick down here.");
  618. X            case TT_WEB:
  619. X            case TT_BEARTRAP:
  620. X            You("can't move your %s!", body_part(LEG));
  621. X        }
  622. X        return(0);
  623. X    }
  624. X
  625. X    if(!getdir(NULL)) return(0);
  626. X    if(!u.dx && !u.dy) return(0);
  627. X
  628. X    x = u.ux + u.dx;
  629. X    y = u.uy + u.dy;
  630. X
  631. X    if(u.uswallow) {
  632. X        switch(rn2(3)) {
  633. X        case 0:  You("can't move your %s!", body_part(LEG));
  634. X             break;
  635. X        case 1:  if (is_animal(u.ustuck->data)) {
  636. X                pline("%s burps loudly.", Monnam(u.ustuck));
  637. X                break;
  638. X             }
  639. X        default: Your("feeble kick has no effect."); break;
  640. X        }
  641. X        return(1);
  642. X    }
  643. X
  644. X    wake_nearby();
  645. X    u_wipe_engr(2);
  646. X
  647. X    maploc = &levl[x][y];
  648. X
  649. X    /* The next four tests should stay in      */
  650. X    /* their present order: monsters, objects, */
  651. X    /* non-doors, doors.               */
  652. X
  653. X    if(MON_AT(x, y)) {
  654. X        kick_monster(x, y);
  655. X        if((Is_airlevel(&u.uz) || Levitation) && flags.move) {
  656. X            int range;
  657. X            struct monst *mon;
  658. X
  659. X            mon = m_at(x,y);
  660. X            range = (3*(int)mon->data->cwt) /
  661. X            ((int)uasmon->cwt + (weight_cap() + inv_weight()));
  662. X            if(range < 1) range = 1;
  663. X            hurtle(-u.dx, -u.dy, range);
  664. X        }
  665. X        return(1);
  666. X    }
  667. X
  668. X    kickobj = (struct obj *)0;
  669. X    if (OBJ_AT(x, y) &&
  670. X        (!Levitation || Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)
  671. X         || sobj_at(BOULDER,x,y))) {
  672. X        if(kick_object(x, y)) {
  673. X            if(Is_airlevel(&u.uz))
  674. X            hurtle(-u.dx, -u.dy, 1); /* assume it's light */
  675. X            return(1);
  676. X        }
  677. X        goto ouch;
  678. X    }
  679. X
  680. X    if(!IS_DOOR(maploc->typ)) {
  681. X        if(maploc->typ == SDOOR) {
  682. X            if(!Levitation && rn2(30) < avrg_attrib) {
  683. X            pline("Crash!  You kick open a secret door!");
  684. X            exercise(A_DEX, TRUE);
  685. X            maploc->typ = DOOR;
  686. X            if(maploc->doormask & D_TRAPPED) {
  687. X                b_trapped("door");
  688. X                maploc->doormask = D_NODOOR;
  689. X            } else
  690. X                maploc->doormask = D_ISOPEN;
  691. X            if (Blind)
  692. X                feel_location(x,y);    /* we know its gone */
  693. X            else
  694. X                newsym(x,y);
  695. X            unblock_point(x,y);    /* vision */
  696. X            return(1);
  697. X            } else goto ouch;
  698. X        }
  699. X        if(maploc->typ == SCORR) {
  700. X            if(!Levitation && rn2(30) < avrg_attrib) {
  701. X            pline("Crash!  You kick open a secret passage!");
  702. X            exercise(A_DEX, TRUE);
  703. X            maploc->typ = CORR;
  704. X            if (Blind)
  705. X                feel_location(x,y);    /* we known its gone */
  706. X            else
  707. X                newsym(x,y);
  708. X            unblock_point(x,y);    /* vision */
  709. X            return(1);
  710. X            } else goto ouch;
  711. X        }
  712. X        if(IS_THRONE(maploc->typ)) {
  713. X            register int i;
  714. X            if(Levitation) goto dumb;
  715. X            if((Luck < 0 || maploc->doormask) && !rn2(3)) {
  716. X            maploc->typ = ROOM;
  717. X            maploc->doormask = 0; /* don't leave loose ends.. */
  718. X            mkgold((long)rnd(200), x, y);
  719. X            if (Blind)
  720. X                pline("CRASH!  You destroy it.");
  721. X            else {
  722. X                pline("CRASH!  You destroy the throne.");
  723. X                newsym(x, y);
  724. X            }
  725. X            exercise(A_DEX, TRUE);
  726. X            return(1);
  727. X            } else if(Luck > 0 && !rn2(3) && !maploc->looted) {
  728. X            mkgold((long) rn1(201, 300), x, y);
  729. X            i = Luck + 1;
  730. X            if(i > 6) i = 6;
  731. X            while(i--) (void) mkobj_at(GEM_CLASS, x, y, TRUE);
  732. X            if (Blind)
  733. X                You("kick something loose!");
  734. X            else {
  735. X                You("kick loose some ornamental coins and gems!");
  736. X                newsym(x, y);
  737. X            }
  738. X            /* prevent endless milking */
  739. X            maploc->looted = T_LOOTED;
  740. X            return(1);
  741. X            } else if (!rn2(4)) {
  742. X            if(dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz)) {
  743. X                fall_through(FALSE);
  744. X                return(1);
  745. X            } else goto ouch;
  746. X            }
  747. X            goto ouch;
  748. X        }
  749. X        if(IS_ALTAR(maploc->typ)) {
  750. X            if(Levitation) goto dumb;
  751. X            You("kick %s.",(Blind ? "something" : "the altar"));
  752. X            if(!rn2(3)) goto ouch;
  753. X            altar_wrath(x, y);
  754. X            exercise(A_DEX, TRUE);
  755. X            return(1);
  756. X        }
  757. X#ifdef SINKS
  758. X        if(IS_SINK(maploc->typ)) {
  759. X            if(Levitation) goto dumb;
  760. X            if(rn2(5)) {
  761. X            if(flags.soundok)
  762. X                pline("Klunk!  The pipes vibrate noisily.");
  763. X            else pline("Klunk!");
  764. X            exercise(A_DEX, TRUE);
  765. X            return(1);
  766. X            } else if(!(maploc->looted & S_LPUDDING) && !rn2(3) &&
  767. X              !(mons[PM_BLACK_PUDDING].geno &
  768. X                (G_GENOD | G_EXTINCT))) {
  769. X            if (Blind)
  770. X                You("hear a gushing sound.");
  771. X            else
  772. X                pline("A %s ooze gushes up from the drain!",
  773. X                      Hallucination ? hcolor() : Black);
  774. X            (void) makemon(&mons[PM_BLACK_PUDDING], x, y);
  775. X            exercise(A_DEX, TRUE);
  776. X            newsym(x,y);
  777. X            maploc->looted |= S_LPUDDING;
  778. X            return(1);
  779. X            } else if(!(maploc->looted & S_LDWASHER) && !rn2(3) &&
  780. X# ifndef POLYSELF
  781. X                  poly_gender() != 2 &&
  782. X# endif
  783. X                  !(mons[poly_gender() == 1 ?
  784. X                      PM_INCUBUS : PM_SUCCUBUS].geno &
  785. X                  (G_GENOD | G_EXTINCT))) {
  786. X            /* can't resist... */
  787. X            pline("%s returns!", (Blind ? "Something" :
  788. X                            "The dish washer"));
  789. X            if (makemon(&mons[poly_gender() == 1 ?
  790. X                PM_INCUBUS : PM_SUCCUBUS], x, y)) newsym(x,y);
  791. X            maploc->looted |= S_LDWASHER;
  792. X            exercise(A_DEX, TRUE);
  793. X            return(1);
  794. X            } else if(!rn2(3)) {
  795. X            pline("Flupp!  %s.", (Blind ?
  796. X                      "You hear a sloshing sound" :
  797. X                      "Muddy waste pops up from the drain"));
  798. X            if(!(maploc->looted & S_LRING)) { /* once per sink */
  799. X                if (!Blind)
  800. X                You("see a ring shining in its midst.");
  801. X                (void) mkobj_at(RING_CLASS, x, y, TRUE);
  802. X                newsym(x, y);
  803. X                exercise(A_DEX, TRUE);
  804. X                exercise(A_WIS, TRUE);    /* a discovery! */
  805. X                maploc->looted |= S_LRING;
  806. X            }
  807. X            return(1);
  808. X            }
  809. X            goto ouch;
  810. X        }
  811. X#endif
  812. X        if (maploc->typ == STAIRS || maploc->typ == LADDER ||
  813. X                            IS_STWALL(maploc->typ)) {
  814. X            if(!IS_STWALL(maploc->typ) && maploc->ladder == LA_DOWN)
  815. X            goto dumb;
  816. Xouch:
  817. X            pline("Ouch!  That hurts!");
  818. X            exercise(A_DEX, FALSE);
  819. X            exercise(A_STR, FALSE);
  820. X            if (Blind) feel_location(x,y); /* we know we hit it */
  821. X            if(!rn2(3)) set_wounded_legs(RIGHT_SIDE, 5 + rnd(5));
  822. X            losehp(rnd(ACURR(A_CON) > 15 ? 3 : 5), kickstr(),
  823. X            KILLED_BY);
  824. X            if(Is_airlevel(&u.uz) || Levitation)
  825. X            hurtle(-u.dx, -u.dy, rn1(2,4)); /* assume it's heavy */
  826. X            return(1);
  827. X        }
  828. X        if (is_drawbridge_wall(x,y) >= 0) {
  829. X            pline("The drawbridge is unaffected.");
  830. X            if(Levitation)
  831. X            hurtle(-u.dx, -u.dy, rn1(2,4)); /* it's heavy */
  832. X            return(1);
  833. X        }
  834. X        goto dumb;
  835. X    }
  836. X
  837. X    if(maploc->doormask == D_ISOPEN ||
  838. X       maploc->doormask == D_BROKEN ||
  839. X       maploc->doormask == D_NODOOR) {
  840. Xdumb:
  841. X        exercise(A_DEX, FALSE);
  842. X        if (martial() || ACURR(A_DEX) >= 16 || rn2(3)) {
  843. X            You("kick at empty space.");
  844. X        } else {
  845. X            pline("Dumb move!  You strain a muscle.");
  846. X            exercise(A_STR, FALSE);
  847. X            set_wounded_legs(RIGHT_SIDE, 5 + rnd(5));
  848. X        }
  849. X        if(Is_airlevel(&u.uz) || Levitation)
  850. X            hurtle(-u.dx, -u.dy, rn2(2));
  851. X        return(0);
  852. X    }
  853. X
  854. X    /* not enough leverage to kick open doors while levitating */
  855. X    if(Levitation) goto ouch;
  856. X
  857. X    exercise(A_DEX, TRUE);
  858. X    /* door is known to be CLOSED or LOCKED */
  859. X    if(rnl(35) < avrg_attrib + (!martial() ? 0 : ACURR(A_DEX))) {
  860. X        /* break the door */
  861. X        if(maploc->doormask & D_TRAPPED) {
  862. X            pline("As you kick the door, it explodes!");
  863. X            exercise(A_STR, FALSE);
  864. X            b_trapped("door");
  865. X            maploc->doormask = D_NODOOR;
  866. X        } else if(ACURR(A_STR) > 18 && !rn2(5) &&
  867. X              !*in_rooms(x, y, SHOPBASE)) {
  868. X            pline("As you kick the door, it shatters to pieces!");
  869. X            exercise(A_STR, TRUE);
  870. X            maploc->doormask = D_NODOOR;
  871. X        } else {
  872. X            pline("As you kick the door, it crashes open!");
  873. X            exercise(A_STR, TRUE);
  874. X            if(*in_rooms(x, y, SHOPBASE)) {
  875. X            add_damage(x, y, 400L);
  876. X            pay_for_damage("break");
  877. X            }
  878. X            maploc->doormask = D_BROKEN;
  879. X        }
  880. X        if (Blind)
  881. X            feel_location(x,y);        /* we know we broke it */
  882. X        else
  883. X            newsym(x,y);
  884. X        unblock_point(x,y);        /* vision */
  885. X    } else {
  886. X        if (Blind) feel_location(x,y);    /* we know we hit it */
  887. X        exercise(A_STR, TRUE);
  888. X        pline("WHAMMM!!!");
  889. X    }
  890. X    return(1);
  891. X}
  892. X
  893. Xstatic const char *
  894. Xgate_str(gate)
  895. Xregister xchar gate;
  896. X{
  897. X    const char *optr;
  898. X
  899. X    switch(gate) {
  900. X        case 0:
  901. X        case 4:  optr = "through the trap door."; break;
  902. X        case 1:
  903. X        case 3:  optr = "down the stairs."; break;
  904. X        case 2:  optr = "down the ladder."; break;
  905. X        default: optr = "down out of sight."; break;
  906. X    }
  907. X    return(optr);
  908. X}
  909. X
  910. Xstatic
  911. Xvoid
  912. Xdrop_to(cc, loc)
  913. Xcoord *cc;
  914. Xregister xchar loc;
  915. X{
  916. X    switch(loc) {
  917. X        case 0: if(In_endgame(&u.uz) || (Is_botlevel(&u.uz) &&
  918. X                  !Is_stronghold(&u.uz))) {
  919. X            cc->y = 0;
  920. X            return;
  921. X            }
  922. X            if(Is_stronghold(&u.uz)) {
  923. X            cc->x = valley_level.dnum;
  924. X            cc->y = valley_level.dlevel;
  925. X            break;
  926. X            } /* else fall to the next cases */
  927. X        case 1:
  928. X        case 2:
  929. X            cc->x = u.uz.dnum;
  930. X            cc->y = u.uz.dlevel + 1;
  931. X            break;
  932. X        case 3:
  933. X            cc->x = sstairs.tolev.dnum;
  934. X            cc->y = sstairs.tolev.dlevel;
  935. X            break;
  936. X        default:
  937. X            cc->y = 0;
  938. X    }
  939. X}
  940. X
  941. Xvoid
  942. Ximpact_drop(missile, x, y, dlev)
  943. Xregister struct obj *missile;
  944. Xregister xchar x, y, dlev;
  945. X{
  946. X    xchar toloc;
  947. X    register struct obj *obj, *obj2;
  948. X    register struct monst *shkp;
  949. X    long oct, dct, price, debit, robbed;
  950. X    boolean angry, costly, isrock;
  951. X    coord cc;
  952. X
  953. X    if(!OBJ_AT(x, y)) return;
  954. X
  955. X    toloc = down_gate(x, y);
  956. X    drop_to(&cc, toloc);
  957. X    if (!cc.y) return;
  958. X
  959. X    if (dlev) {
  960. X        /* send objects next to player falling through trap door.
  961. X         * checked in obj_delivery().
  962. X         */
  963. X        toloc = 4;
  964. X        cc.y = dlev;
  965. X    }
  966. X
  967. X    costly = costly_spot(x, y);
  968. X    price = debit = robbed = 0L;
  969. X    angry = FALSE;
  970. X    shkp = (struct monst *) 0;
  971. X    /* if 'costly', we must keep a record of ESHK(shkp) before
  972. X     * it undergoes changes through the calls to stolen_value.
  973. X     * the angry bit must be reset, if needed, in this fn, since
  974. X     * stolen_value is called under the 'silent' flag to avoid
  975. X     * unsavory pline repetitions.
  976. X     */
  977. X    if(costly) {
  978. X        if((shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) != 
  979. X                                               (struct monst *)0) {
  980. X        debit    = ESHK(shkp)->debit;
  981. X        robbed    = ESHK(shkp)->robbed;
  982. X        angry    = !shkp->mpeaceful;
  983. X        }
  984. X    }
  985. X
  986. X    isrock = (missile && missile->otyp == ROCK);
  987. X    oct = dct = 0L;
  988. X    for(obj = level.objects[x][y]; obj; obj = obj2) {
  989. X        obj2 = obj->nexthere;
  990. X        if(obj == missile) continue;
  991. X        /* number of objects in the pile */
  992. X        oct += obj->quan;
  993. X        /* boulders can fall too, but rarely & never due to rocks */
  994. X        if((isrock && obj->otyp == BOULDER) ||
  995. X           rn2(obj->otyp == BOULDER ? 30 : 3)) continue;
  996. X        freeobj(obj);
  997. X
  998. X        if(costly) {
  999. X            price += stolen_value(obj, x, y,
  1000. X                (costly_spot(u.ux, u.uy) &&
  1001. X                 index(u.urooms, *in_rooms(x, y, SHOPBASE))),
  1002. X                TRUE);
  1003. X            /* set obj->no_charge to 0 */
  1004. X            if(Is_container(obj))
  1005. X                picked_container(obj); /* does the right thing */
  1006. X            if(obj->otyp != GOLD_PIECE)
  1007. X                obj->no_charge = 0;
  1008. X        }
  1009. X        obj->nobj = migrating_objs;
  1010. X        migrating_objs = obj;
  1011. X
  1012. X        obj->ox = cc.x;
  1013. X        obj->oy = cc.y;
  1014. X        obj->owornmask = (long)toloc;
  1015. X
  1016. X        /* number of fallen objects */
  1017. X        dct += obj->quan;
  1018. X    }
  1019. X
  1020. X    if (dct) {    /* at least one object fell */
  1021. X        const char *what = (dct == 1L ? "object falls" : "objects fall");
  1022. X        if (missile)
  1023. X        pline("From the impact, %sother %s.",
  1024. X            dct == oct ? "the " : dct == 1L ? "an" : "", what);
  1025. X        else
  1026. X        pline("%s adjacent %s %s",
  1027. X            oct == dct ? (dct > 1L ? "All the" : "The") :
  1028. X                (dct == 1L ? "One of the" : "Some of the"),
  1029. X            what, gate_str(toloc));
  1030. X    }
  1031. X
  1032. X    if(costly && shkp && price) {
  1033. X        if(ESHK(shkp)->robbed > robbed) {
  1034. X            You("removed %ld zorkmids worth of goods!", price);
  1035. X            if(cansee(shkp->mx, shkp->my)) {
  1036. X            if(ESHK(shkp)->customer[0] == 0)
  1037. X                (void) strncpy(ESHK(shkp)->customer,
  1038. X                       plname, PL_NSIZ);
  1039. X            if(angry)
  1040. X                pline("%s is infuriated!", Monnam(shkp));
  1041. X            else pline("\"%s, you are a thief!\"", plname);
  1042. X            } else  You("hear a scream, \"Thief!\"");
  1043. X            hot_pursuit(shkp);
  1044. X            (void) angry_guards(FALSE);
  1045. X            return;
  1046. X        }
  1047. X        if(ESHK(shkp)->debit > debit)
  1048. X            You("owe %s %ld zorkmids for goods lost.",
  1049. X            Monnam(shkp),
  1050. X            (ESHK(shkp)->debit - debit));
  1051. X    }
  1052. X
  1053. X}
  1054. X
  1055. X/* NOTE: ship_object assumes otmp was FREED from fobj or invent.
  1056. X * <x,y> is the point of drop.  otmp is _not_ an <x,y> resident:
  1057. X * otmp is either a kicked, dropped, or thrown object.
  1058. X */
  1059. Xboolean
  1060. Xship_object(otmp, x, y, shop_floor_obj)
  1061. Xregister xchar  x, y;
  1062. Xregister struct obj *otmp;
  1063. Xregister boolean shop_floor_obj;
  1064. X{
  1065. X    register xchar ox, oy;
  1066. X    register xchar toloc = down_gate(x, y);
  1067. X    /* toloc -- destination location: */
  1068. X        /*    0: rnd loc,
  1069. X         *    1: <,
  1070. X         *    2: < ladder,
  1071. X         *    3: sstairs up
  1072. X         *    4: near player (trapdoor)
  1073. X         */
  1074. X    coord cc;
  1075. X    /* objects always fall down ladder, a chance of stay otherwise */
  1076. X    register boolean nodrop = (toloc != 2 && rn2(3));
  1077. X    register boolean unpaid, container, impact = FALSE;
  1078. X    int n = 0;
  1079. X
  1080. X    if(!otmp) return(FALSE);
  1081. X    if(toloc == -1) return(FALSE);
  1082. X
  1083. X    drop_to(&cc, toloc);
  1084. X    if(!cc.y) return(FALSE);
  1085. X
  1086. X    container = Is_container(otmp);
  1087. X
  1088. X    unpaid = (otmp->unpaid || (container && count_unpaid(otmp->cobj)));
  1089. X
  1090. X    if(OBJ_AT(x, y)) {
  1091. X        register struct obj *obj;
  1092. X
  1093. X        for(obj = level.objects[x][y]; obj; obj = obj->nexthere)
  1094. X        if(obj != otmp) n++;
  1095. X        if(n) impact = TRUE;
  1096. X    }
  1097. X
  1098. X    otransit_msg(otmp, toloc, nodrop, n);
  1099. X
  1100. X    if(nodrop) {
  1101. X        otmp->nobj = fobj;
  1102. X        fobj = otmp;
  1103. X        place_object(otmp, x, y);
  1104. X        stackobj(otmp);
  1105. X        newsym(otmp->ox, otmp->oy);
  1106. X        if(impact) goto chain_reaction;
  1107. X        else return(TRUE);
  1108. X    }
  1109. X
  1110. X    if(unpaid || shop_floor_obj) {
  1111. X        if(unpaid) {
  1112. X        subfrombill(otmp, shop_keeper(*u.ushops));
  1113. X        (void)stolen_value(otmp, u.ux, u.uy, TRUE, FALSE);
  1114. X        } else {
  1115. X            ox = otmp->ox;
  1116. X        oy = otmp->oy;
  1117. X        (void)stolen_value(otmp, ox, oy,
  1118. X              (costly_spot(u.ux, u.uy) &&
  1119. X                  index(u.urooms, *in_rooms(ox, oy, SHOPBASE))),
  1120. X              FALSE);
  1121. X        }
  1122. X        /* set otmp->no_charge to 0 */
  1123. X        if(container)
  1124. X            picked_container(otmp); /* happens to do the right thing */
  1125. X        if(otmp->otyp != GOLD_PIECE)
  1126. X            otmp->no_charge = 0;
  1127. X    }
  1128. X
  1129. X    otmp->nobj = migrating_objs;
  1130. X    migrating_objs = otmp;
  1131. X
  1132. X    otmp->ox = cc.x;
  1133. X    otmp->oy = cc.y;
  1134. X    otmp->owornmask = (long)toloc;
  1135. Xchain_reaction:
  1136. X    if(impact) {
  1137. X        /* the objs impacted may be in a shop other than
  1138. X         * the one in which the hero is located.  another
  1139. X         * check for a shk is made in impact_drop.  it is, e.g.,
  1140. X         * possible to kick/throw an object belonging to one
  1141. X         * shop into another shop through a gap in the wall,
  1142. X         * and cause objects belonging to the other shop to
  1143. X         * fall down a trapdoor--thereby getting two shopkeepers
  1144. X         * angry at the hero in one shot.
  1145. X         */
  1146. X        impact_drop(otmp, x, y, 0);
  1147. X        newsym(x,y);
  1148. X    }
  1149. X    return(TRUE);
  1150. X}
  1151. X
  1152. Xvoid
  1153. Xobj_delivery()
  1154. X{
  1155. X    register struct obj *otmp, *otmp0 = (struct obj *)0, *otmp2;
  1156. X
  1157. X    for(otmp = migrating_objs; otmp; otmp = otmp2) {
  1158. X
  1159. X        otmp2 = otmp->nobj;
  1160. X
  1161. X        if(otmp->ox == u.uz.dnum && otmp->oy == u.uz.dlevel) {
  1162. X        if(otmp == migrating_objs)
  1163. X            migrating_objs = otmp->nobj;
  1164. X        else
  1165. X            otmp0->nobj = otmp->nobj;
  1166. X        otmp->nobj = fobj;
  1167. X        fobj = otmp;
  1168. X
  1169. X        switch((xchar)otmp->owornmask) {
  1170. X            xchar *xlocale, *ylocale;
  1171. X
  1172. X            case 1: xlocale = &xupstair; ylocale = &yupstair;
  1173. X                goto common;
  1174. X            case 2: xlocale = &xupladder; ylocale = &yupladder;
  1175. X                goto common;
  1176. X            case 3: xlocale = &sstairs.sx; ylocale = &sstairs.sy;
  1177. X                goto common;
  1178. X            case 4: { /* hero falls down trapdoor with objects */
  1179. X                  xchar nx, ny;
  1180. X                  int cnt = 0;
  1181. X
  1182. X                  do {
  1183. X                  nx = u.ux - 1 + rn2(3);
  1184. X                  ny = u.uy - 1 + rn2(3);
  1185. X                  } while((nx < 1 || nx > COLNO-2 ||
  1186. X                       ny < 1 || ny > ROWNO-2 ||
  1187. X                       is_pool(nx,ny) || is_lava(nx,ny) ||
  1188. X                       !ACCESSIBLE(levl[nx][ny].typ) ||
  1189. X                       closed_door(nx, ny)
  1190. X                      ) && cnt++ <= 50);
  1191. X
  1192. X                  if(cnt >= 50) goto scatter; /* safety */
  1193. X                  xlocale = &nx;
  1194. X                  ylocale = &ny;
  1195. X                }
  1196. Xcommon:
  1197. X                if (*xlocale && *ylocale) {
  1198. X                place_object(otmp, *xlocale, *ylocale);
  1199. X                stackobj(otmp);
  1200. X                break;
  1201. X                } /* else fall through */
  1202. X            default:
  1203. Xscatter:
  1204. X                rloco(otmp);
  1205. X                break;
  1206. X        }
  1207. X        otmp->owornmask = 0L;
  1208. X        } else
  1209. X        otmp0 = otmp;
  1210. X    }
  1211. X}
  1212. X
  1213. Xstatic void
  1214. Xotransit_msg(otmp, loc, nodrop, num)
  1215. Xregister struct obj *otmp;
  1216. Xregister xchar loc;
  1217. Xregister boolean nodrop;
  1218. Xint num;
  1219. X{
  1220. X    char obuf[BUFSZ];
  1221. X
  1222. X    Sprintf(obuf, "%s%s",
  1223. X         (otmp->otyp == CORPSE &&
  1224. X            type_is_pname(&mons[otmp->corpsenm])) ? "" : "The ",
  1225. X         xname(otmp));
  1226. X
  1227. X    if(num) { /* means: other objects are impacted */
  1228. X        Sprintf(eos(obuf), " hit%s %s object%s",
  1229. X              otmp->quan == 1L ? "s" : "",
  1230. X              num == 1 ? "another" : "other",
  1231. X              num > 1 ? "s" : "");
  1232. X        if(nodrop)
  1233. X        Sprintf(eos(obuf), " and stop%s.",
  1234. X                 otmp->quan == 1L ? "s" : "");
  1235. X        else
  1236. X        Sprintf(eos(obuf), " and fall%s %s",
  1237. X                otmp->quan == 1L ? "s" : "", gate_str(loc));
  1238. X        pline(obuf);
  1239. X    } else if(!nodrop)
  1240. X        pline("%s fall%s %s", obuf,
  1241. X          otmp->quan == 1L ? "s" : "",
  1242. X          gate_str(loc));
  1243. X}
  1244. X
  1245. Xxchar
  1246. Xdown_gate(x, y)
  1247. Xxchar x, y;
  1248. X{
  1249. X    register struct trap *ttmp = t_at(x, y);
  1250. X
  1251. X    if(ttmp && ttmp->ttyp == TRAPDOOR && ttmp->tseen) return 0;
  1252. X    if(xdnstair == x && ydnstair == y) return 1;
  1253. X    if(xdnladder == x && ydnladder == y) return 2;
  1254. X    if(sstairs.sx == x && sstairs.sy == y && !sstairs.up) return 3;
  1255. X    return -1;
  1256. X}
  1257. X
  1258. X/*dokick.c*/
  1259. END_OF_FILE
  1260. if test 32287 -ne `wc -c <'src/dokick.c'`; then
  1261.     echo shar: \"'src/dokick.c'\" unpacked with wrong size!
  1262. fi
  1263. # end of 'src/dokick.c'
  1264. fi
  1265. if test -f 'sys/amiga/splitter/split.doc' -a "${1}" != "-c" ; then 
  1266.   echo shar: Will not clobber existing file \"'sys/amiga/splitter/split.doc'\"
  1267. else
  1268. echo shar: Extracting \"'sys/amiga/splitter/split.doc'\" \(1323 characters\)
  1269. sed "s/^X//" >'sys/amiga/splitter/split.doc' <<'END_OF_FILE'
  1270. X    Splitter            [split.doc 93/01/08]
  1271. X
  1272. XUsage:
  1273. X    splitter [-Cc_prototype] [-Dd_prototype] [-ddir_prototype] binary
  1274. X
  1275. XDefault prototypes:
  1276. X    d: %n.dir
  1277. X    C: %n.c%C
  1278. X    D: %n.d%D
  1279. X
  1280. XPrototypes:
  1281. X    %n    base file name
  1282. X    %C    current code file #
  1283. X    %D    current data file #
  1284. X
  1285. XCreates:
  1286. X    binary.dir        directions file
  1287. X    binary.d00        data files
  1288. X    binary.d01 ...
  1289. X    binary.c00        code files
  1290. X    binary.c01 ...
  1291. X
  1292. XFormat of the directions file (subject to change):
  1293. X    Cbinary.c00
  1294. X    Cbinary.c01
  1295. X    Cbinary.c02
  1296. X    Dbinary.d00
  1297. X    Dbinary.d01
  1298. XThe above entries may be edited to reflect the location of the various files
  1299. Xif it is necessary for them to be moved by the user.  All C entries must
  1300. Xpreceed all D entries.
  1301. X
  1302. XMaximum output file size is 800K (819200 bytes) - this leaves just enough
  1303. Xspace on an empty floppy for a small icon.
  1304. X
  1305. XCode file contents:
  1306. XThe first code file contains:
  1307. X    the (modified) HUNK_HEADER from the original binary
  1308. X    (followed by)
  1309. XAll code files contain:
  1310. X    HUNK_CODE's from the original binary
  1311. X
  1312. XData file contents:
  1313. X    HUNK_BSS's from the original binary
  1314. X    HUNK_DATA's from the original binary
  1315. X
  1316. XCOMPILING
  1317. X    [SASC5]
  1318. X    lc -L splitter.c arg.c
  1319. X
  1320. XBUGS
  1321. X    The present system for generating multiple files is a hack -
  1322. X    multi.[ch] should be upgraded instead.
  1323. X
  1324. X    Many optimizations for minimizing the size of the output file
  1325. X    could/should/will be added.
  1326. X
  1327. X    Not tested with SASC 6.0 yet.
  1328. END_OF_FILE
  1329. if test 1323 -ne `wc -c <'sys/amiga/splitter/split.doc'`; then
  1330.     echo shar: \"'sys/amiga/splitter/split.doc'\" unpacked with wrong size!
  1331. fi
  1332. # end of 'sys/amiga/splitter/split.doc'
  1333. fi
  1334. if test -f 'win/tty/termcap.c' -a "${1}" != "-c" ; then 
  1335.   echo shar: Will not clobber existing file \"'win/tty/termcap.c'\"
  1336. else
  1337. echo shar: Extracting \"'win/tty/termcap.c'\" \(19701 characters\)
  1338. sed "s/^X//" >'win/tty/termcap.c' <<'END_OF_FILE'
  1339. X/*    SCCS Id: @(#)termcap.c    3.1    92/11/15    */
  1340. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  1341. X/* NetHack may be freely redistributed.  See license for details. */
  1342. X
  1343. X#include "hack.h"
  1344. X#include "wintty.h"
  1345. X
  1346. X#include "termcap.h"
  1347. X
  1348. X
  1349. X#ifdef MICROPORT_286_BUG
  1350. X#define Tgetstr(key) (tgetstr(key,tbuf))
  1351. X#else
  1352. X#define Tgetstr(key) (tgetstr(key,&tbufptr))
  1353. X#endif /* MICROPORT_286_BUG **/
  1354. X
  1355. Xvoid FDECL(cmov, (int, int));
  1356. Xvoid FDECL(nocmov, (int, int));
  1357. X#ifdef TEXTCOLOR
  1358. X# ifdef TERMLIB
  1359. X#  ifdef OVLB
  1360. X#   ifndef TOS
  1361. Xstatic void FDECL(analyze_seq, (char *, int *, int *));
  1362. X#   endif
  1363. Xstatic void NDECL(init_hilite);
  1364. X#  endif /* OVLB */
  1365. X# endif
  1366. X#endif
  1367. X
  1368. X#ifdef OVLB
  1369. X    /* (see termcap.h) -- CM, ND, CD, HI,HE, US,UE, ul_hack */
  1370. Xstruct tc_lcl_data tc_lcl_data = { 0, 0, 0, 0,0, 0,0, FALSE };
  1371. X#endif /* OVLB */
  1372. X
  1373. XSTATIC_VAR char *HO, *CL, *CE, *UP, *XD, *BC, *SO, *SE, *TI, *TE;
  1374. XSTATIC_VAR char *VS, *VE;
  1375. X#if 0
  1376. XSTATIC_VAR char *MR, *ME;
  1377. XSTATIC_VAR char *MB, *MH;
  1378. XSTATIC_VAR char *MD;     /* may already be in use below */
  1379. X#endif
  1380. X#ifdef TERMLIB
  1381. X# ifdef TEXTCOLOR
  1382. XSTATIC_VAR char *MD;
  1383. X# endif
  1384. XSTATIC_VAR int SG;
  1385. X#ifdef OVLB
  1386. XSTATIC_OVL char PC = '\0';
  1387. X#else /* OVLB */
  1388. XSTATIC_DCL char PC;
  1389. X#endif /* OVLB */
  1390. XSTATIC_VAR char tbuf[512];
  1391. X#endif
  1392. X
  1393. X#ifdef TEXTCOLOR
  1394. X# ifdef TOS
  1395. Xconst char *hilites[MAXCOLORS];    /* terminal escapes for the various colors */
  1396. X# else
  1397. Xchar NEARDATA *hilites[MAXCOLORS]; /* terminal escapes for the various colors */
  1398. X# endif
  1399. X#endif
  1400. X
  1401. X#ifdef OVLB
  1402. Xstatic char *KS = NULL, *KE = NULL;    /* keypad sequences */
  1403. Xstatic char nullstr[] = "";
  1404. X#endif /* OVLB */
  1405. X
  1406. X#ifndef TERMLIB
  1407. XSTATIC_VAR char tgotobuf[20];
  1408. X# ifdef TOS
  1409. X#define tgoto(fmt, x, y)    (Sprintf(tgotobuf, fmt, y+' ', x+' '), tgotobuf)
  1410. X# else
  1411. X#define tgoto(fmt, x, y)    (Sprintf(tgotobuf, fmt, y+1, x+1), tgotobuf)
  1412. X# endif
  1413. X#endif /* TERMLIB */
  1414. X
  1415. X#ifdef OVLB
  1416. X
  1417. Xvoid
  1418. Xtty_startup(wid, hgt)
  1419. X    int *wid, *hgt;
  1420. X{
  1421. X#ifdef TERMLIB
  1422. X    register const char *term;
  1423. X    register char *tptr;
  1424. X    char *tbufptr, *pc;
  1425. X#endif
  1426. X    register int i;
  1427. X
  1428. X#ifdef TERMLIB
  1429. X# ifdef VMS
  1430. X    if (!(term = verify_termcap()))
  1431. X# endif
  1432. X    term = getenv("TERM");
  1433. X#endif
  1434. X
  1435. X#ifdef TERMLIB
  1436. X    if(!term)
  1437. X#endif
  1438. X#if defined(TOS) && defined(__GNUC__) && defined(TERMLIB)
  1439. X        term = "builtin";        /* library has a default */
  1440. X#else
  1441. X#  ifdef ANSI_DEFAULT
  1442. X#   ifdef TOS
  1443. X    {
  1444. X        CO = 80; LI = 25;
  1445. X        TI = VS = VE = TE = nullstr;
  1446. X        HO = "\033H";
  1447. X        CL = "\033E";        /* the VT52 termcap */
  1448. X        CE = "\033K";
  1449. X        UP = "\033A";
  1450. X        CM = "\033Y%c%c";    /* used with function tgoto() */
  1451. X        ND = "\033C";
  1452. X        XD = "\033B";
  1453. X        BC = "\033D";
  1454. X        SO = "\033p";
  1455. X        SE = "\033q";
  1456. X    /* HI and HE will be updated in init_hilite if we're using color */
  1457. X        HI = "\033p";
  1458. X        HE = "\033q";
  1459. X    }
  1460. X#   else /* TOS */
  1461. X    {
  1462. X#    ifdef MICRO
  1463. X        get_scr_size();
  1464. X#     ifdef CLIPPING
  1465. X        if(CO < COLNO || LI < ROWNO+3)
  1466. X            setclipped();
  1467. X#     endif
  1468. X#    endif
  1469. X        HO = "\033[H";
  1470. X        CL = "\033[2J";        /* the ANSI termcap */
  1471. X/*        CD = "\033[J"; */
  1472. X        CE = "\033[K";
  1473. X#    ifndef TERMLIB
  1474. X        CM = "\033[%d;%dH";
  1475. X#    else
  1476. X        CM = "\033[%i%d;%dH";
  1477. X#    endif
  1478. X        UP = "\033[A";
  1479. X        ND = "\033[C";
  1480. X        XD = "\033[B";
  1481. X#    ifdef MICRO    /* backspaces are non-destructive */
  1482. X        BC = "\b";
  1483. X#    else
  1484. X        BC = "\033[D";
  1485. X#    endif
  1486. X        HI = SO = "\033[1m";
  1487. X        US = "\033[4m";
  1488. X#    if 0
  1489. X        MR = "\033[7m";
  1490. X        ME = "\033[0m";
  1491. X#    endif
  1492. X        TI = HE = SE = UE = "\033[0m";
  1493. X        /* strictly, SE should be 2, and UE should be 24,
  1494. X           but we can't trust all ANSI emulators to be
  1495. X           that complete.  -3. */
  1496. X#    ifndef MICRO
  1497. X        AS = "\016";
  1498. X        AE = "\017";
  1499. X#    endif
  1500. X        TE = VS = VE = nullstr;
  1501. X#    ifdef TEXTCOLOR
  1502. X        for (i = 0; i < MAXCOLORS / 2; i++)
  1503. X            if (i != BLACK) {
  1504. X            hilites[i|BRIGHT] = (char *) alloc(sizeof("\033[1;3%dm"));
  1505. X            Sprintf(hilites[i|BRIGHT], "\033[1;3%dm", i);
  1506. X            if (i != GRAY)
  1507. X#     ifdef MICRO
  1508. X                if (i == BLUE) hilites[BLUE] = hilites[BLUE|BRIGHT];
  1509. X                else
  1510. X#     endif
  1511. X                {
  1512. X                hilites[i] = (char *) alloc(sizeof("\033[0;3%dm"));
  1513. X                Sprintf(hilites[i], "\033[0;3%dm", i);
  1514. X                }
  1515. X            }
  1516. X#    endif
  1517. X        *wid = CO;
  1518. X        *hgt = LI;
  1519. X        return;
  1520. X    }
  1521. X#   endif /* TOS */
  1522. X#  else
  1523. X        error("Can't get TERM.");
  1524. X#  endif /* ANSI_DEFAULT */
  1525. X#endif /* __GNUC__ && TOS && TERMCAP */
  1526. X#ifdef TERMLIB
  1527. X    tptr = (char *) alloc(1024);
  1528. X
  1529. X    tbufptr = tbuf;
  1530. X    if(!strncmp(term, "5620", 4))
  1531. X        flags.null = FALSE;    /* this should be a termcap flag */
  1532. X    if(tgetent(tptr, term) < 1)
  1533. X        error("Unknown terminal type: %s.", term);
  1534. X    if ((pc = Tgetstr("pc")) != 0)
  1535. X        PC = *pc;
  1536. X
  1537. X    if(!(BC = Tgetstr("le")))    /* both termcap and terminfo use le */    
  1538. X# ifdef TERMINFO
  1539. X        error("Terminal must backspace.");
  1540. X# else
  1541. X        if(!(BC = Tgetstr("bc"))) {    /* termcap also uses bc/bs */
  1542. X#  if !defined(MINIMAL_TERM)
  1543. X        if(!tgetflag("bs"))
  1544. X            error("Terminal must backspace.");
  1545. X#  endif
  1546. X        BC = tbufptr;
  1547. X        tbufptr += 2;
  1548. X        *BC = '\b';
  1549. X        }
  1550. X# endif
  1551. X
  1552. X# ifdef MINIMAL_TERM
  1553. X    HO = NULL;
  1554. X# else
  1555. X    HO = Tgetstr("ho");
  1556. X# endif
  1557. X    /*
  1558. X     * LI and CO are set in ioctl.c via a TIOCGWINSZ if available.  If
  1559. X     * the kernel has values for either we should use them rather than
  1560. X     * the values from TERMCAP ...
  1561. X     */
  1562. X# ifndef MICRO
  1563. X    if (!CO) CO = tgetnum("co");
  1564. X    if (!LI) LI = tgetnum("li");
  1565. X# else
  1566. X#  if defined(TOS) && defined(__GNUC__)
  1567. X    if (!strcmp(term, "builtin"))
  1568. X        get_scr_size();
  1569. X    else {
  1570. X#  endif
  1571. X    CO = tgetnum("co");
  1572. X    LI = tgetnum("li");
  1573. X    if (!LI || !CO)            /* if we don't override it */
  1574. X        get_scr_size();
  1575. X#  if defined(TOS) && defined(__GNUC__)
  1576. X    }
  1577. X#  endif
  1578. X# endif
  1579. X# ifdef CLIPPING
  1580. X    if(CO < COLNO || LI < ROWNO+3)
  1581. X        setclipped();
  1582. X# endif
  1583. X    if(!(CL = Tgetstr("cl")))
  1584. X        error("Hack needs CL.");
  1585. X    ND = Tgetstr("nd");
  1586. X    if(tgetflag("os"))
  1587. X        error("Hack can't have OS.");
  1588. X    if(tgetflag("ul"))
  1589. X        ul_hack = TRUE;
  1590. X    CE = Tgetstr("ce");
  1591. X    UP = Tgetstr("up");
  1592. X    /* It seems that xd is no longer supported, and we should use
  1593. X       a linefeed instead; unfortunately this requires resetting
  1594. X       CRMOD, and many output routines will have to be modified
  1595. X       slightly. Let's leave that till the next release. */
  1596. X    XD = Tgetstr("xd");
  1597. X/* not:         XD = Tgetstr("do"); */
  1598. X    if(!(CM = Tgetstr("cm"))) {
  1599. X        if(!UP && !HO)
  1600. X            error("Hack needs CM or UP or HO.");
  1601. X        tty_raw_print("Playing hack on terminals without cm is suspect...");
  1602. X        tty_wait_synch();
  1603. X    }
  1604. X    SO = Tgetstr("so");
  1605. X    SE = Tgetstr("se");
  1606. X    US = Tgetstr("us");
  1607. X    UE = Tgetstr("ue");
  1608. X    SG = tgetnum("sg");    /* -1: not fnd; else # of spaces left by so */
  1609. X    if(!SO || !SE || (SG > 0)) SO = SE = US = UE = nullstr;
  1610. X    TI = Tgetstr("ti");
  1611. X    TE = Tgetstr("te");
  1612. X    VS = VE = nullstr;
  1613. X# ifdef TERMINFO
  1614. X    VS = Tgetstr("eA");    /* enable graphics */
  1615. X# endif
  1616. X    KS = Tgetstr("ks");    /* keypad start (special mode) */
  1617. X    KE = Tgetstr("ke");    /* keypad end (ordinary mode [ie, digits]) */
  1618. X# if 0
  1619. X    MR = Tgetstr("mr");    /* reverse */
  1620. X    MB = Tgetstr("mb");    /* blink */
  1621. X    MD = Tgetstr("md");    /* boldface */
  1622. X    MH = Tgetstr("mh");    /* dim */
  1623. X    ME = Tgetstr("me");
  1624. X# endif
  1625. X
  1626. X    /* Get rid of padding numbers for HI and HE.  Hope they
  1627. X     * aren't really needed!!!  HI and HE are ouputted to the
  1628. X     * pager as a string - so how can you send it NULLS???
  1629. X     *  -jsb
  1630. X     */
  1631. X        HI = (char *) alloc((unsigned)(strlen(SO)+1));
  1632. X        HE = (char *) alloc((unsigned)(strlen(SE)+1));
  1633. X        i = 0;
  1634. X        while (digit(SO[i])) i++;
  1635. X        Strcpy(HI, &SO[i]);
  1636. X        i = 0;
  1637. X        while (digit(SE[i])) i++;
  1638. X        Strcpy(HE, &SE[i]);
  1639. X    AS = Tgetstr("as");
  1640. X    AE = Tgetstr("ae");
  1641. X    CD = Tgetstr("cd");
  1642. X# ifdef TEXTCOLOR
  1643. X    MD = Tgetstr("md");
  1644. X# endif
  1645. X    if(tbufptr-tbuf > sizeof(tbuf)) error("TERMCAP entry too big...\n");
  1646. X    free((genericptr_t)tptr);
  1647. X# ifdef TEXTCOLOR
  1648. X#  if defined(TOS) && defined(__GNUC__)
  1649. X    if (!strcmp(term, "builtin") || !strcmp(term, "tw52")) {
  1650. X        init_hilite();
  1651. X    }
  1652. X#  else
  1653. X    init_hilite();
  1654. X#  endif
  1655. X# endif
  1656. X#endif /* TERMLIB */
  1657. X    *wid = CO;
  1658. X    *hgt = LI;
  1659. X}
  1660. X
  1661. Xvoid
  1662. Xtty_number_pad(state)
  1663. Xint state;
  1664. X{
  1665. X    switch (state) {
  1666. X        case -1:    /* activate keypad mode (escape sequences) */
  1667. X            if (KS && *KS) xputs(KS);
  1668. X            break;
  1669. X        case  1:    /* activate numeric mode for keypad (digits) */
  1670. X            if (KE && *KE) xputs(KE);
  1671. X            break;
  1672. X        case  0:    /* don't need to do anything--leave terminal as-is */
  1673. X        default:
  1674. X            break;
  1675. X    }
  1676. X}
  1677. X
  1678. X#ifdef TERMLIB
  1679. Xextern void NDECL((*decgraphics_mode_callback));    /* defined in drawing.c */
  1680. Xstatic void NDECL(tty_decgraphics_termcap_fixup);
  1681. X
  1682. X/*
  1683. X   We call this routine whenever DECgraphics mode is enabled, even if it
  1684. X   has been previously set, in case the user manages to reset the fonts.
  1685. X   The actual termcap fixup only needs to be done once, but we can't
  1686. X   call xputs() from the option setting or graphics assigning routines,
  1687. X   so this is a convenient hook.
  1688. X */
  1689. Xstatic void
  1690. Xtty_decgraphics_termcap_fixup()
  1691. X{
  1692. X    static char ctrlN[]   = "\016";
  1693. X    static char ctrlO[]   = "\017";
  1694. X    static char appMode[] = "\033=";
  1695. X    static char numMode[] = "\033>";
  1696. X
  1697. X    /* these values are missing from some termcaps */
  1698. X    if (!AS) AS = ctrlN;    /* ^N (shift-out [graphics font]) */
  1699. X    if (!AE) AE = ctrlO;    /* ^O (shift-in  [regular font])  */
  1700. X    if (!KS) KS = appMode;    /* ESC= (application keypad mode) */
  1701. X    if (!KE) KE = numMode;    /* ESC> (numeric keypad mode)      */
  1702. X    /*
  1703. X     * Select the line-drawing character set as the alternate font.
  1704. X     * Do not select NA ASCII as the primary font since people may
  1705. X     * reasonably be using the UK character set.
  1706. X     */
  1707. X    if (flags.DECgraphics) xputs("\033)0");
  1708. X}
  1709. X#endif
  1710. X
  1711. Xvoid
  1712. Xtty_start_screen()
  1713. X{
  1714. X    xputs(TI);
  1715. X    xputs(VS);
  1716. X#ifdef TERMLIB
  1717. X    if (flags.DECgraphics) tty_decgraphics_termcap_fixup();
  1718. X    /* set up callback in case option is not set yet but toggled later */
  1719. X    decgraphics_mode_callback = tty_decgraphics_termcap_fixup;
  1720. X#endif
  1721. X    if (flags.num_pad) tty_number_pad(1);    /* make keypad send digits */
  1722. X}
  1723. X
  1724. Xvoid
  1725. Xtty_end_screen()
  1726. X{
  1727. X    clear_screen();
  1728. X    xputs(VE);
  1729. X    xputs(TE);
  1730. X}
  1731. X
  1732. X/* Cursor movements */
  1733. X
  1734. X#endif /* OVLB */
  1735. X
  1736. X#ifdef OVL0
  1737. X/* Note to OVLx tinkerers.  The placement of this overlay controls the location
  1738. X   of the function xputc().  This function is not currently in trampoli.[ch]
  1739. X   files for what is deemed to be performance reasons.  If this define is moved
  1740. X   and or xputc() is taken out of the ROOT overlay, then action must be taken
  1741. X   in trampoli.[ch]. */
  1742. X
  1743. Xvoid
  1744. Xnocmov(x, y)
  1745. Xint x,y;
  1746. X{
  1747. X    if ((int) ttyDisplay->cury > y) {
  1748. X        if(UP) {
  1749. X            while ((int) ttyDisplay->cury > y) {    /* Go up. */
  1750. X                xputs(UP);
  1751. X                ttyDisplay->cury--;
  1752. X            }
  1753. X        } else if(CM) {
  1754. X            cmov(x, y);
  1755. X        } else if(HO) {
  1756. X            home();
  1757. X            tty_curs(BASE_WINDOW, x+1, y);
  1758. X        } /* else impossible("..."); */
  1759. X    } else if ((int) ttyDisplay->cury < y) {
  1760. X        if(XD) {
  1761. X            while((int) ttyDisplay->cury < y) {
  1762. X                xputs(XD);
  1763. X                ttyDisplay->cury++;
  1764. X            }
  1765. X        } else if(CM) {
  1766. X            cmov(x, y);
  1767. X        } else {
  1768. X            while((int) ttyDisplay->cury < y) {
  1769. X                xputc('\n');
  1770. X                ttyDisplay->curx = 0;
  1771. X                ttyDisplay->cury++;
  1772. X            }
  1773. X        }
  1774. X    }
  1775. X    if ((int) ttyDisplay->curx < x) {        /* Go to the right. */
  1776. X        if(!ND) cmov(x, y); else    /* bah */
  1777. X            /* should instead print what is there already */
  1778. X        while ((int) ttyDisplay->curx < x) {
  1779. X            xputs(ND);
  1780. X            ttyDisplay->curx++;
  1781. X        }
  1782. X    } else if ((int) ttyDisplay->curx > x) {
  1783. X        while ((int) ttyDisplay->curx > x) {    /* Go to the left. */
  1784. X            xputs(BC);
  1785. X            ttyDisplay->curx--;
  1786. X        }
  1787. X    }
  1788. X}
  1789. X
  1790. Xvoid
  1791. Xcmov(x, y)
  1792. Xregister int x, y;
  1793. X{
  1794. X    xputs(tgoto(CM, x, y));
  1795. X    ttyDisplay->cury = y;
  1796. X    ttyDisplay->curx = x;
  1797. X}
  1798. X
  1799. X/* See note at OVLx ifdef above.   xputc() is a special function. */
  1800. Xvoid
  1801. Xxputc(c)
  1802. X#if defined(apollo)
  1803. Xint c;
  1804. X#else
  1805. Xchar c;
  1806. X#endif
  1807. X{
  1808. X    (void) putchar(c);
  1809. X}
  1810. X
  1811. Xvoid
  1812. Xxputs(s)
  1813. Xconst char *s;
  1814. X{
  1815. X# ifndef TERMLIB
  1816. X    (void) fputs(s, stdout);
  1817. X# else
  1818. X#  if defined(NHSTDC) || defined(ULTRIX_PROTO)
  1819. X    tputs(s, 1, (int (*)())xputc);
  1820. X#  else
  1821. X    tputs(s, 1, xputc);
  1822. X#  endif
  1823. X# endif
  1824. X}
  1825. X
  1826. Xvoid
  1827. Xcl_end()
  1828. X{
  1829. X    if(CE)
  1830. X        xputs(CE);
  1831. X    else {    /* no-CE fix - free after Harold Rynes */
  1832. X        /* this looks terrible, especially on a slow terminal
  1833. X           but is better than nothing */
  1834. X        register int cx = ttyDisplay->curx+1;
  1835. X
  1836. X        while(cx < CO) {
  1837. X            xputc(' ');
  1838. X            cx++;
  1839. X        }
  1840. X        tty_curs(BASE_WINDOW, (int)ttyDisplay->curx+1,
  1841. X                        (int)ttyDisplay->cury);
  1842. X    }
  1843. X}
  1844. X
  1845. X#endif /* OVL0 */
  1846. X#ifdef OVLB
  1847. X
  1848. Xvoid
  1849. Xclear_screen()
  1850. X{
  1851. X    /* note: if CL is null, then termcap initialization failed,
  1852. X        so don't attempt screen-oriented I/O during final cleanup.
  1853. X     */
  1854. X    if (CL) {
  1855. X        xputs(CL);
  1856. X        home();
  1857. X    }
  1858. X}
  1859. X
  1860. X#endif /* OVLB */
  1861. X#ifdef OVL0
  1862. X
  1863. Xvoid
  1864. Xhome()
  1865. X{
  1866. X    if(HO)
  1867. X        xputs(HO);
  1868. X    else if(CM)
  1869. X        xputs(tgoto(CM, 0, 0));
  1870. X    else
  1871. X        tty_curs(BASE_WINDOW, 1, 0);    /* using UP ... */
  1872. X    ttyDisplay->curx = ttyDisplay->cury = 0;
  1873. X}
  1874. X
  1875. Xvoid
  1876. Xstandoutbeg()
  1877. X{
  1878. X    if(SO) xputs(SO);
  1879. X}
  1880. X
  1881. Xvoid
  1882. Xstandoutend()
  1883. X{
  1884. X    if(SE) xputs(SE);
  1885. X}
  1886. X
  1887. X#if 0    /* if you need one of these, uncomment it (here and in extern.h) */
  1888. Xvoid
  1889. Xrevbeg()
  1890. X{
  1891. X    if(MR) xputs(MR);
  1892. X}
  1893. X
  1894. Xvoid
  1895. Xboldbeg()
  1896. X{
  1897. X    if(MD) xputs(MD);
  1898. X}
  1899. X
  1900. Xvoid
  1901. Xblinkbeg()
  1902. X{
  1903. X    if(MB) xputs(MB);
  1904. X}
  1905. X
  1906. Xvoid
  1907. Xdimbeg()
  1908. X/* not in most termcap entries */
  1909. X{
  1910. X    if(MH) xputs(MH);
  1911. X}
  1912. X
  1913. Xvoid
  1914. Xm_end()
  1915. X{
  1916. X    if(ME) xputs(ME);
  1917. X}
  1918. X#endif
  1919. X
  1920. X#endif /* OVL0 */
  1921. X#ifdef OVLB
  1922. X
  1923. Xvoid
  1924. Xbacksp()
  1925. X{
  1926. X    xputs(BC);
  1927. X}
  1928. X
  1929. Xvoid
  1930. Xtty_nhbell()
  1931. X{
  1932. X    if (flags.silent) return;
  1933. X    (void) putchar('\007');        /* curx does not change */
  1934. X    (void) fflush(stdout);
  1935. X}
  1936. X
  1937. X#endif /* OVLB */
  1938. X#ifdef OVL0
  1939. X
  1940. X#ifdef ASCIIGRAPH
  1941. Xvoid
  1942. Xgraph_on() {
  1943. X    if (AS) xputs(AS);
  1944. X}
  1945. X
  1946. Xvoid
  1947. Xgraph_off() {
  1948. X    if (AE) xputs(AE);
  1949. X}
  1950. X#endif
  1951. X
  1952. X#endif /* OVL0 */
  1953. X#ifdef OVL1
  1954. X
  1955. X#if !defined(MICRO)
  1956. X# ifdef VMS
  1957. Xstatic const short tmspc10[] = {        /* from termcap */
  1958. X    0, 2000, 1333, 909, 743, 666, 333, 166, 83, 55, 50, 41, 27, 20, 13, 10,
  1959. X    5
  1960. X};
  1961. X# else
  1962. Xstatic const short tmspc10[] = {        /* from termcap */
  1963. X    0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5
  1964. X};
  1965. X# endif
  1966. X#endif
  1967. X
  1968. Xvoid
  1969. Xtty_delay_output()
  1970. X{
  1971. X    /* delay 50 ms - could also use a 'nap'-system call */
  1972. X    /* BUG: if the padding character is visible, as it is on the 5620
  1973. X       then this looks terrible. */
  1974. X#if defined(MICRO)
  1975. X    /* simulate the delay with "cursor here" */
  1976. X    register int i;
  1977. X    for (i = 0; i < 3; i++) {
  1978. X        cmov(ttyDisplay->curx, ttyDisplay->cury);
  1979. X        (void) fflush(stdout);
  1980. X    }
  1981. X#else /* MICRO */
  1982. X    if(flags.null)
  1983. X# ifdef TERMINFO
  1984. X        /* cbosgd!cbcephus!pds for SYS V R2 */
  1985. X#  ifdef NHSTDC
  1986. X        tputs("$<50>", 1, (int (*)())xputc);
  1987. X#  else
  1988. X        tputs("$<50>", 1, xputc);
  1989. X#  endif
  1990. X# else
  1991. X#  if defined(NHSTDC) || defined(ULTRIX_PROTO)
  1992. X        tputs("50", 1, (int (*)())xputc);
  1993. X#  else
  1994. X        tputs("50", 1, xputc);
  1995. X#  endif
  1996. X# endif
  1997. X
  1998. X    else if(ospeed > 0 && ospeed < SIZE(tmspc10)) if(CM) {
  1999. X        /* delay by sending cm(here) an appropriate number of times */
  2000. X        register int cmlen = strlen(tgoto(CM, ttyDisplay->curx, ttyDisplay->cury));
  2001. X        register int i = 500 + tmspc10[ospeed]/2;
  2002. X
  2003. X        while(i > 0) {
  2004. X            cmov((int)ttyDisplay->curx, (int)ttyDisplay->cury);
  2005. X            i -= cmlen*tmspc10[ospeed];
  2006. X        }
  2007. X    }
  2008. X#endif /* MICRO */
  2009. X}
  2010. X
  2011. X#endif /* OVL1 */
  2012. X#ifdef OVLB
  2013. X
  2014. Xvoid
  2015. Xcl_eos()            /* free after Robert Viduya */
  2016. X{                /* must only be called with curx = 1 */
  2017. X
  2018. X    if(CD)
  2019. X        xputs(CD);
  2020. X    else {
  2021. X        register int cy = ttyDisplay->cury+1;
  2022. X        while(cy <= LI-2) {
  2023. X            cl_end();
  2024. X            xputc('\n');
  2025. X            cy++;
  2026. X        }
  2027. X        cl_end();
  2028. X        tty_curs(BASE_WINDOW, (int)ttyDisplay->curx+1,
  2029. X                        (int)ttyDisplay->cury);
  2030. X    }
  2031. X}
  2032. X
  2033. X#if defined(TEXTCOLOR) && defined(TERMLIB)
  2034. X# if defined(UNIX) && defined(TERMINFO)
  2035. X/*
  2036. X * Sets up color highlighting, using terminfo(4) escape sequences (highlight
  2037. X * code found in print.c).  It is assumed that the background color is black.
  2038. X */
  2039. X/* terminfo indexes for the basic colors it guarantees */
  2040. X#define COLOR_BLACK   1        /* fake out to avoid black on black */
  2041. X#define COLOR_BLUE    1
  2042. X#define COLOR_GREEN   2
  2043. X#define COLOR_CYAN    3
  2044. X#define COLOR_RED     4
  2045. X#define COLOR_MAGENTA 5
  2046. X#define COLOR_YELLOW  6
  2047. X#define COLOR_WHITE   7
  2048. X
  2049. X/* map ANSI RGB to terminfo BGR */
  2050. Xconst int ti_map[8] = {
  2051. X    COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW,
  2052. X    COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE };
  2053. X
  2054. Xstatic void
  2055. Xinit_hilite()
  2056. X{
  2057. X    register int c;
  2058. X    char *setf, *scratch;
  2059. X    extern char *tparm();
  2060. X
  2061. X    for (c = 0; c < SIZE(hilites); c++)
  2062. X        hilites[c] = HI;
  2063. X    hilites[GRAY] = hilites[NO_COLOR] = NULL;
  2064. X
  2065. X    if (tgetnum("Co") < 8 || (setf = tgetstr("Sf", (char **)0)) == NULL)
  2066. X        return;
  2067. X
  2068. X    for (c = 0; c < MAXCOLORS / 2; c++) {
  2069. X          scratch = tparm(setf, ti_map[c]);
  2070. X        if (c != GRAY) {
  2071. X            hilites[c] = (char *) alloc(strlen(scratch) + 1);
  2072. X            Strcpy(hilites[c], scratch);
  2073. X        }
  2074. X        if (c != BLACK) {
  2075. X            hilites[c|BRIGHT] = (char*) alloc(strlen(scratch)+strlen(MD)+1);
  2076. X            Strcpy(hilites[c|BRIGHT], MD);
  2077. X            Strcat(hilites[c|BRIGHT], scratch);
  2078. X            }
  2079. X        
  2080. X    }
  2081. X}
  2082. X
  2083. X# else /* UNIX && TERMINFO */
  2084. X
  2085. X#  ifndef TOS
  2086. X/* find the foreground and background colors set by HI or HE */
  2087. Xstatic void
  2088. Xanalyze_seq (str, fg, bg)
  2089. Xchar *str;
  2090. Xint *fg, *bg;
  2091. X{
  2092. X    register int c, code;
  2093. X    int len;
  2094. X
  2095. X#   ifdef MICRO
  2096. X    *fg = GRAY; *bg = BLACK;
  2097. X#   else
  2098. X    *fg = *bg = NO_COLOR;
  2099. X#   endif
  2100. X
  2101. X    if (str[0] != '\033' || str[1] != '[' ||
  2102. X        str[len = strlen(str) - 1] != 'm' || len < 3)
  2103. X        return;
  2104. X
  2105. X    c = 2;
  2106. X    while (c < len) {
  2107. X        if ((code = atoi(&str[c])) == 0) { /* reset */
  2108. X        /* this also catches errors */
  2109. X#   ifdef MICRO
  2110. X        *fg = GRAY; *bg = BLACK;
  2111. X#   else
  2112. X        *fg = *bg = NO_COLOR;
  2113. X#   endif
  2114. X        } else if (code == 1) { /* bold */
  2115. X        *fg |= BRIGHT;
  2116. X#   if 0
  2117. X    /* I doubt we'll ever resort to using blinking characters,
  2118. X       unless we want a pulsing glow for something.  But, in case
  2119. X       we do... - 3. */
  2120. X        } else if (code == 5) { /* blinking */
  2121. X        *fg |= BLINK;
  2122. X        } else if (code == 25) { /* stop blinking */
  2123. X        *fg &= ~BLINK;
  2124. X#   endif
  2125. X        } else if (code == 7 || code == 27) { /* reverse */
  2126. X        code = *fg & ~BRIGHT;
  2127. X        *fg = *bg | (*fg & BRIGHT);
  2128. X        *bg = code;
  2129. X        } else if (code >= 30 && code <= 37) { /* hi_foreground RGB */
  2130. X        *fg = code - 30;
  2131. X        } else if (code >= 40 && code <= 47) { /* hi_background RGB */
  2132. X        *bg = code - 40;
  2133. X        }
  2134. X        while (digit(str[++c]));
  2135. X        c++;
  2136. X    }
  2137. X}
  2138. X#  endif
  2139. X
  2140. X/*
  2141. X * Sets up highlighting sequences, using ANSI escape sequences (highlight code
  2142. X * found in print.c).  The HI and HE sequences (usually from SO) is scanned to
  2143. X * find foreground and background colors.
  2144. X */
  2145. X
  2146. Xstatic void
  2147. Xinit_hilite()
  2148. X{
  2149. X    register int c;
  2150. X#  ifdef TOS
  2151. X    extern unsigned long tos_numcolors;    /* in tos.c */
  2152. X    static const char NOCOL[] = "\033b0", COLHE[] = "\033q\033b0";
  2153. X
  2154. X    HI = "\033p";
  2155. X#  else
  2156. X    int backg, foreg, hi_backg, hi_foreg;
  2157. X#  endif
  2158. X
  2159. X    for (c = 0; c < SIZE(hilites); c++)
  2160. X        hilites[c] = HI;
  2161. X    hilites[GRAY] = hilites[NO_COLOR] = NULL;
  2162. X
  2163. X#  ifdef TOS
  2164. X    if (tos_numcolors <= 2) {
  2165. X        return;
  2166. X    }
  2167. X/* Under TOS, the "bright" and "dim" colors are reversed. Moreover,
  2168. X * on the Falcon the dim colors are *really* dim; so we make most
  2169. X * of the colors the bright versions, with a few exceptions where
  2170. X * the dim ones look OK.
  2171. X */
  2172. X    hilites[0] = NOCOL;
  2173. X    for (c = 1; c < SIZE(hilites); c++) {
  2174. X        hilites[c] = (char *) alloc(sizeof("\033b0"));
  2175. X        if (tos_numcolors > 4)
  2176. X            Sprintf(hilites[c], "\033b%c", (c&~BRIGHT)+'0');
  2177. X        else
  2178. X            Strcpy(hilites[c], HI);
  2179. X    }
  2180. X
  2181. X    if (tos_numcolors == 4) {
  2182. X        TI = "\033b0\033c3\033E\033e";
  2183. X        TE = "\033b3\033c0\033J";
  2184. X        HE = COLHE;
  2185. X        hilites[GREEN] = hilites[GREEN|BRIGHT] = "\033b2";
  2186. X        hilites[RED] = hilites[RED|BRIGHT] = "\033b1";
  2187. X    } else {
  2188. X        sprintf(hilites[BROWN], "\033b%c", (BROWN^BRIGHT)+'0');
  2189. X        sprintf(hilites[GREEN], "\033b%c", (GREEN^BRIGHT)+'0');
  2190. X
  2191. X        TI = "\033b0\033c\017\033E\033e";
  2192. X        TE = "\033b\017\033c0\033J";
  2193. X        HE = COLHE;
  2194. X        hilites[WHITE] = hilites[BLACK] = NOCOL;
  2195. X        hilites[NO_COLOR] = hilites[GRAY];
  2196. X    }
  2197. X
  2198. X#  else /* TOS */
  2199. X    analyze_seq(HI, &hi_foreg, &hi_backg);
  2200. X    analyze_seq(HE, &foreg, &backg);
  2201. X
  2202. X    for (c = 0; c < SIZE(hilites); c++)
  2203. X        /* avoid invisibility */
  2204. X        if ((backg & ~BRIGHT) != c) {
  2205. X#   ifdef MICRO
  2206. X        if (c == BLUE) continue;
  2207. X#   endif
  2208. X        if (c == foreg)
  2209. X            hilites[c] = NULL;
  2210. X        else if (c != hi_foreg && backg != hi_backg) {
  2211. X            hilites[c] = (char *) alloc(sizeof("\033[%d;3%d;4%dm"));
  2212. X            Sprintf(hilites[c], "\033[%d", !!(c & BRIGHT));
  2213. X            if ((c | BRIGHT) != (foreg | BRIGHT))
  2214. X            Sprintf(eos(hilites[c]), ";3%d", c & ~BRIGHT);
  2215. X            if (backg != BLACK)
  2216. X            Sprintf(eos(hilites[c]), ";4%d", backg & ~BRIGHT);
  2217. X            Strcat(hilites[c], "m");
  2218. X        }
  2219. X        }
  2220. X
  2221. X#   ifdef MICRO
  2222. X    /* brighten low-visibility colors */
  2223. X    hilites[BLUE] = hilites[BLUE|BRIGHT];
  2224. X#   endif
  2225. X#  endif /* TOS */
  2226. X}
  2227. X# endif /* UNIX */
  2228. X#endif /* TEXTCOLOR */
  2229. X
  2230. X#endif /* OVLB */
  2231. X
  2232. X/*termcap.c*/
  2233. END_OF_FILE
  2234. if test 19701 -ne `wc -c <'win/tty/termcap.c'`; then
  2235.     echo shar: \"'win/tty/termcap.c'\" unpacked with wrong size!
  2236. fi
  2237. # end of 'win/tty/termcap.c'
  2238. fi
  2239. echo shar: End of archive 59 \(of 108\).
  2240. cp /dev/null ark59isdone
  2241. MISSING=""
  2242. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
  2243. 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
  2244. 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
  2245. 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
  2246. 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 \
  2247. 101 102 103 104 105 106 107 108 ; do
  2248.     if test ! -f ark${I}isdone ; then
  2249.     MISSING="${MISSING} ${I}"
  2250.     fi
  2251. done
  2252. if test "${MISSING}" = "" ; then
  2253.     echo You have unpacked all 108 archives.
  2254.     echo "Now execute 'rebuild.sh'"
  2255.     rm -f ark10[0-8]isdone ark[1-9]isdone ark[1-9][0-9]isdone
  2256. else
  2257.     echo You still need to unpack the following archives:
  2258.     echo "        " ${MISSING}
  2259. fi
  2260. ##  End of shell archive.
  2261. exit 0
  2262.