1 /* NetHack 3.6 worm.c $NHDT-Date: 1456528599 2016/02/26 23:16:39 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.20 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2009. */
4 /* NetHack may be freely redistributed. See license for details. */
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2018 */
9 /* JNetHack may be freely redistributed. See license for details. */
14 #define newseg() (struct wseg *) alloc(sizeof (struct wseg))
15 #define dealloc_seg(wseg) free((genericptr_t) (wseg))
17 /* worm segment structure */
20 xchar wx, wy; /* the segment's position */
23 STATIC_DCL void FDECL(toss_wsegs, (struct wseg *, BOOLEAN_P));
24 STATIC_DCL void FDECL(shrink_worm, (int));
25 STATIC_DCL void FDECL(random_dir, (XCHAR_P, XCHAR_P, xchar *, xchar *));
26 STATIC_DCL struct wseg *FDECL(create_worm_tail, (int));
28 /* Description of long worm implementation.
30 * Each monst struct of the head of a tailed worm has a wormno set to
31 * 1 <= wormno < MAX_NUM_WORMS
32 * If wormno == 0 this does not mean that the monster is not a worm,
33 * it just means that the monster does not have a long worm tail.
35 * The actual segments of a worm are not full blown monst structs.
36 * They are small wseg structs, and their position in the levels.monsters[][]
37 * array is held by the monst struct of the head of the worm. This makes
38 * things like probing and hit point bookkeeping much easier.
40 * The segments of the long worms on a level are kept as an array of
41 * singly threaded linked lists. The wormno variable is used as an index
42 * for these segment arrays.
44 * wtails: The first (starting struct) of a linked list. This points
45 * to the tail (last) segment of the worm.
47 * wheads: The last (end) of a linked list of segments. This points to
48 * the segment that is at the same position as the real monster
49 * (the head). Note that the segment that wheads[wormno] points
50 * to, is not displayed. It is simply there to keep track of
51 * where the head came from, so that worm movement and display
52 * are simplified later.
53 * Keeping the head segment of the worm at the end of the list
54 * of tail segments is an endless source of confusion, but it is
56 * From now on, we will use "start" and "end" to refer to the
57 * linked list and "head" and "tail" to refer to the worm.
59 * One final worm array is:
61 * wgrowtime: This tells us when to add another segment to the worm.
63 * When a worm is moved, we add a new segment at the head, and delete the
64 * segment at the tail (unless we want it to grow). This new head segment is
65 * located in the same square as the actual head of the worm. If we want
66 * to grow the worm, we don't delete the tail segment, and we give the worm
67 * extra hit points, which possibly go into its maximum.
69 * Non-moving worms (worm_nomove) are assumed to be surrounded by their own
70 * tail, and, thus, shrink instead of grow (as their tails keep going while
71 * their heads are stopped short). In this case, we delete the last tail
72 * segment, and remove hit points from the worm.
75 struct wseg *wheads[MAX_NUM_WORMS] = DUMMY, *wtails[MAX_NUM_WORMS] = DUMMY;
76 long wgrowtime[MAX_NUM_WORMS] = DUMMY;
81 * Find an unused worm tail slot and return the index. A zero means that
82 * there are no slots available. This means that the worm head can exist,
83 * it just cannot ever grow a tail.
85 * It, also, means that there is an optimisation to made. The [0] positions
86 * of the arrays are never used. Meaning, we really *could* have one more
87 * tailed worm on the level, or use a smaller array (using wormno - 1).
89 * Implementation is left to the interested hacker.
94 register int new_wormno = 1;
96 while (new_wormno < MAX_NUM_WORMS) {
97 if (!wheads[new_wormno])
98 return new_wormno; /* found empty wtails[] slot at new_wormno */
101 return 0; /* level infested with worms */
107 * Use if (mon->wormno = get_wormno()) before calling this function!
109 * Initialize the worm entry. This will set up the worm grow time, and
110 * create and initialize the dummy segment for wheads[] and wtails[].
112 * If the worm has no tail (ie get_wormno() fails) then this function need
116 initworm(worm, wseg_count)
120 register struct wseg *seg, *new_tail = create_worm_tail(wseg_count);
121 register int wnum = worm->wormno;
123 /* if (!wnum) return; bullet proofing */
126 wtails[wnum] = new_tail;
127 for (seg = new_tail; seg->nseg; seg = seg->nseg)
131 wtails[wnum] = wheads[wnum] = seg = newseg();
132 seg->nseg = (struct wseg *) 0;
136 wgrowtime[wnum] = 0L;
142 * Get rid of all worm segments on and following the given pointer curr.
143 * The display may or may not need to be updated as we free the segments.
147 toss_wsegs(curr, display_update)
148 register struct wseg *curr;
149 register boolean display_update;
151 register struct wseg *seg;
156 /* remove from level.monsters[][] */
158 /* need to check curr->wx for genocided while migrating_mon */
160 remove_monster(curr->wx, curr->wy);
162 /* update screen before deallocation */
164 newsym(curr->wx, curr->wy);
167 /* free memory used by the segment */
176 * Remove the tail segment of the worm (the starting segment of the list).
181 int wnum; /* worm number */
185 if (wtails[wnum] == wheads[wnum])
186 return; /* no tail */
189 wtails[wnum] = seg->nseg;
190 seg->nseg = (struct wseg *) 0;
191 toss_wsegs(seg, TRUE);
197 * Check for mon->wormno before calling this function!
199 * Move the worm. Maybe grow.
205 register struct wseg *seg, *new_seg; /* new segment */
206 register int wnum = worm->wormno; /* worm number */
208 /* if (!wnum) return; bullet proofing */
211 * Place a segment at the old worm head. The head has already moved.
214 place_worm_seg(worm, seg->wx, seg->wy);
215 newsym(seg->wx, seg->wy); /* display the new segment */
218 * Create a new dummy segment head and place it at the end of the list.
221 new_seg->wx = worm->mx;
222 new_seg->wy = worm->my;
223 new_seg->nseg = (struct wseg *) 0;
224 seg->nseg = new_seg; /* attach it to the end of the list */
225 wheads[wnum] = new_seg; /* move the end pointer */
227 if (wgrowtime[wnum] <= moves) {
228 if (!wgrowtime[wnum])
229 wgrowtime[wnum] = moves + rnd(5);
231 wgrowtime[wnum] += rn1(15, 3);
233 if (worm->mhp > MHPMAX)
235 if (worm->mhp > worm->mhpmax)
236 worm->mhpmax = worm->mhp;
238 /* The worm doesn't grow, so the last segment goes away. */
245 * Check for mon->wormno before calling this function!
247 * The worm don't move so it should shrink.
251 register struct monst *worm;
253 shrink_worm((int) worm->wormno); /* shrink */
256 worm->mhp -= 3; /* mhpmax not changed ! */
264 * Check for mon->wormno before calling this function!
270 register struct monst *worm;
272 register int wnum = worm->wormno;
274 /* if (!wnum) return; bullet proofing */
278 /* This will also remove the real monster (ie 'w') from the its
279 * position in level.monsters[][].
281 toss_wsegs(wtails[wnum], TRUE);
283 wheads[wnum] = wtails[wnum] = (struct wseg *) 0;
289 * Check for mon->wormno before calling this function!
291 * If the hero is near any part of the worm, the worm will try to attack.
295 register struct monst *worm;
297 register int wnum = worm->wormno;
298 register struct wseg *seg;
300 /* if (!wnum) return; bullet proofing */
302 /* This does not work right now because mattacku() thinks that the head
303 * is out of range of the player. We might try to kludge, and bring
304 * the head within range for a tiny moment, but this needs a bit more
305 * looking at before we decide to do this.
307 for (seg = wtails[wnum]; seg; seg = seg->nseg)
308 if (distu(seg->wx, seg->wy) < 3)
309 (void) mattacku(worm);
314 * Check for mon->wormno before calling this function!
316 * When hitting a worm (worm) at position x, y, with a weapon (weap),
317 * there is a chance that the worm will be cut in half, and a chance
318 * that both halves will survive.
321 cutworm(worm, x, y, weap)
326 register struct wseg *curr, *new_tail;
327 register struct monst *new_worm;
328 int wnum = worm->wormno;
329 int cut_chance, new_wnum;
332 return; /* bullet proofing */
334 if (x == worm->mx && y == worm->my)
335 return; /* hit on head */
337 /* cutting goes best with a bladed weapon */
338 cut_chance = rnd(20); /* Normally 1-16 does not cut */
339 /* Normally 17-20 does */
341 if (weap && is_blade(weap)) /* With a blade 1- 6 does not cut */
342 cut_chance += 10; /* 7-20 does */
345 return; /* not good enough */
347 /* Find the segment that was attacked. */
350 while ((curr->wx != x) || (curr->wy != y)) {
353 impossible("cutworm: no segment at (%d,%d)", (int) x, (int) y);
358 /* If this is the tail segment, then the worm just loses it. */
359 if (curr == wtails[wnum]) {
365 * Split the worm. The tail for the new worm is the old worm's tail.
366 * The tail for the old worm is the segment that follows "curr",
367 * and "curr" becomes the dummy segment under the new head.
369 new_tail = wtails[wnum];
370 wtails[wnum] = curr->nseg;
371 curr->nseg = (struct wseg *) 0; /* split the worm */
374 * At this point, the old worm is correct. Any new worm will have
375 * it's head at "curr" and its tail at "new_tail". The old worm
376 * must be at least level 3 in order to produce a new worm.
379 new_wnum = (worm->m_lev >= 3 && !rn2(3)) ? get_wormno() : 0;
381 remove_monster(x, y); /* clone_mon puts new head here */
382 /* clone_mon() will fail if enough long worms have been
383 created to have them be marked as extinct or if the hit
384 that cut the current one has dropped it down to 1 HP */
385 new_worm = clone_mon(worm, x, y);
388 /* Sometimes the tail end dies. */
390 if (context.mon_moving) {
391 if (canspotmon(worm))
393 pline("Part of %s tail has been cut off.",
394 s_suffix(mon_nam(worm)));
396 pline("%s
\82Ì
\90K
\94ö
\82Ì
\88ê
\95\94\95ª
\82ª
\90Ø
\82è
\97\8e\82Æ
\82³
\82ê
\82½
\81D",
401 You("cut part of the tail off of %s.", mon_nam(worm));
403 You("%s
\82Ì
\90K
\94ö
\82Ì
\88ê
\95\94\95ª
\82ð
\90Ø
\82Á
\82½
\81D", mon_nam(worm));
404 toss_wsegs(new_tail, TRUE);
410 new_worm->wormno = new_wnum; /* affix new worm number */
411 new_worm->mcloned = 0; /* treat second worm as a normal monster */
413 /* Devalue the monster level of both halves of the worm.
414 Note: m_lev is always at least 3 in order to get this far. */
415 worm->m_lev = max((unsigned) worm->m_lev - 2, 3);
416 new_worm->m_lev = worm->m_lev;
418 /* Calculate the lower-level mhp; use <N>d8 for long worms.
419 Can't use newmonhp() here because it would reset m_lev. */
420 new_worm->mhpmax = new_worm->mhp = d((int) new_worm->m_lev, 8);
421 worm->mhpmax = d((int) worm->m_lev, 8); /* new maxHP for old worm */
422 if (worm->mhpmax < worm->mhp)
423 worm->mhp = worm->mhpmax;
425 wtails[new_wnum] = new_tail; /* We've got all the info right now */
426 wheads[new_wnum] = curr; /* so we can do this faster than */
427 wgrowtime[new_wnum] = 0L; /* trying to call initworm(). */
429 /* Place the new monster at all the segment locations. */
430 place_wsegs(new_worm);
432 if (context.mon_moving)
434 pline("%s is cut in half.", Monnam(worm));
436 pline("%s
\82Í
\90^
\82Á
\82Õ
\82½
\82Â
\82É
\82³
\82ê
\82½
\81D", Monnam(worm));
439 You("cut %s in half.", mon_nam(worm));
441 You("%s
\82ð
\90^
\82Á
\82Õ
\82½
\82Â
\82É
\82µ
\82½
\81D", mon_nam(worm));
447 * Refresh all of the segments of the given worm. This is only called
448 * from see_monster() in display.c or when a monster goes minvis. It
449 * is located here for modularity.
455 struct wseg *curr = wtails[worm->wormno];
457 /* if (!mtmp->wormno) return; bullet proofing */
459 while (curr != wheads[worm->wormno]) {
460 newsym(curr->wx, curr->wy);
468 * Display all of the segments of the given worm for detection.
471 detect_wsegs(worm, use_detection_glyph)
473 boolean use_detection_glyph;
476 struct wseg *curr = wtails[worm->wormno];
478 /* if (!mtmp->wormno) return; bullet proofing */
480 while (curr != wheads[worm->wormno]) {
481 num = use_detection_glyph
482 ? detected_monnum_to_glyph(what_mon(PM_LONG_WORM_TAIL))
484 ? petnum_to_glyph(what_mon(PM_LONG_WORM_TAIL))
485 : monnum_to_glyph(what_mon(PM_LONG_WORM_TAIL)));
486 show_glyph(curr->wx, curr->wy, num);
494 * Save the worm information for later use. The count is the number
495 * of segments, including the dummy. Called from save.c.
503 struct wseg *curr, *temp;
505 if (perform_bwrite(mode)) {
506 for (i = 1; i < MAX_NUM_WORMS; i++) {
507 for (count = 0, curr = wtails[i]; curr; curr = curr->nseg)
509 /* Save number of segments */
510 bwrite(fd, (genericptr_t) &count, sizeof(int));
511 /* Save segment locations of the monster. */
513 for (curr = wtails[i]; curr; curr = curr->nseg) {
514 bwrite(fd, (genericptr_t) & (curr->wx), sizeof(xchar));
515 bwrite(fd, (genericptr_t) & (curr->wy), sizeof(xchar));
519 bwrite(fd, (genericptr_t) wgrowtime, sizeof(wgrowtime));
522 if (release_data(mode)) {
523 /* Free the segments only. savemonchn() will take care of the
525 for (i = 1; i < MAX_NUM_WORMS; i++) {
526 if (!(curr = wtails[i]))
531 dealloc_seg(curr); /* free the segment */
534 wheads[i] = wtails[i] = (struct wseg *) 0;
542 * Restore the worm information from the save file. Called from restore.c
549 struct wseg *curr, *temp;
551 for (i = 1; i < MAX_NUM_WORMS; i++) {
552 mread(fd, (genericptr_t) &count, sizeof(int));
556 /* Get the segments. */
557 for (curr = (struct wseg *) 0, j = 0; j < count; j++) {
559 temp->nseg = (struct wseg *) 0;
560 mread(fd, (genericptr_t) & (temp->wx), sizeof(xchar));
561 mread(fd, (genericptr_t) & (temp->wy), sizeof(xchar));
570 mread(fd, (genericptr_t) wgrowtime, sizeof(wgrowtime));
576 * Place the segments of the given worm. Called from restore.c
582 struct wseg *curr = wtails[worm->wormno];
584 /* if (!mtmp->wormno) return; bullet proofing */
586 while (curr != wheads[worm->wormno]) {
587 place_worm_seg(worm, curr->wx, curr->wy);
593 sanity_check_worm(worm)
601 panic("not a worm?!");
603 curr = wtails[worm->wormno];
605 while (curr != wheads[worm->wormno]) {
606 if (!isok(curr->wx, curr->wy))
607 panic("worm seg not isok");
608 if (level.monsters[curr->wx][curr->wy] != worm)
609 panic("worm not at seg location");
617 * This function is equivalent to the remove_monster #define in
618 * rm.h, only it will take the worm *and* tail out of the levels array.
619 * It does not get rid of (dealloc) the worm tail structures, and it does
620 * not remove the mon from the fmon chain.
624 register struct monst *worm;
626 register struct wseg *curr = wtails[worm->wormno];
628 /* if (!mtmp->wormno) return; bullet proofing */
631 remove_monster(curr->wx, curr->wy);
632 newsym(curr->wx, curr->wy);
638 * place_worm_tail_randomly()
640 * Place a worm tail somewhere on a level behind the head.
641 * This routine essentially reverses the order of the wsegs from head
642 * to tail while placing them.
643 * x, and y are most likely the worm->mx, and worm->my, but don't *need* to
644 * be, if somehow the head is disjoint from the tail.
647 place_worm_tail_randomly(worm, x, y)
651 int wnum = worm->wormno;
652 struct wseg *curr = wtails[wnum];
653 struct wseg *new_tail;
654 register xchar ox = x, oy = y;
656 /* if (!wnum) return; bullet proofing */
658 if (wnum && (!wtails[wnum] || !wheads[wnum])) {
659 impossible("place_worm_tail_randomly: wormno is set without a tail!");
663 wheads[wnum] = new_tail = curr;
665 new_tail->nseg = (struct wseg *) 0;
673 /* pick a random direction from x, y and search for goodpos() */
676 random_dir(ox, oy, &nx, &ny);
677 } while (!goodpos(nx, ny, worm, 0) && (tryct++ < 50));
680 place_worm_seg(worm, nx, ny);
685 wtails[wnum]->nseg = new_tail;
686 new_tail = wtails[wnum];
688 } else { /* Oops. Truncate because there was */
689 toss_wsegs(curr, FALSE); /* no place for the rest of it */
690 curr = (struct wseg *) 0;
696 * Given a coordinate x, y.
697 * return in *nx, *ny, the coordinates of one of the <= 8 squares adjoining.
699 * This function, and the loop it serves, could be eliminated by coding
700 * enexto() with a search radius.
704 random_dir(x, y, nx, ny)
706 register xchar *nx, *ny;
711 *nx += (x > 1 /* extreme left ? */
712 ? (x < COLNO /* extreme right ? */
713 ? (rn2(3) - 1) /* neither so +1, 0, or -1 */
714 : -rn2(2)) /* 0, or -1 */
715 : rn2(2)); /* 0, or 1 */
717 *ny += (*nx == x /* same kind of thing with y */
718 ? (y > 1 ? (y < ROWNO ? (rn2(2) ? 1 : -1) : -1) : 1)
719 : (y > 1 ? (y < ROWNO ? (rn2(3) - 1) : -rn2(2)) : rn2(2)));
722 /* for size_monst(cmd.c) to support #stats */
727 return (int) (count_wsegs(worm) * sizeof (struct wseg));
731 * returns the number of segments that a worm has.
738 register struct wseg *curr;
741 for (curr = wtails[mtmp->wormno]->nseg; curr; curr = curr->nseg)
747 /* create_worm_tail()
748 * will create a worm tail chain of (num_segs + 1) and return pointer to it.
752 create_worm_tail(num_segs)
756 register struct wseg *new_tail, *curr;
759 return (struct wseg *) 0;
761 new_tail = curr = newseg();
762 curr->nseg = (struct wseg *) 0;
766 while (i < num_segs) {
767 curr->nseg = newseg();
769 curr->nseg = (struct wseg *) 0;
779 * Is any segment of this worm in viewing range? Note: caller must check
780 * invisibility and telepathy (which should only show the head anyway).
781 * Mostly used in the canseemon() macro.
787 struct wseg *curr = wtails[worm->wormno];
790 if (cansee(curr->wx, curr->wy))
797 /* would moving from <x1,y1> to <x2,y2> involve passing between two
798 consecutive segments of the same worm? */
800 worm_cross(x1, y1, x2, y2)
804 struct wseg *curr, *wnxt;
807 * With digits representing relative sequence number of the segments,
808 * returns true when testing between @ and ? (passes through worm's
809 * body), false between @ and ! (stays on same side of worm).
816 if (distmin(x1, y1, x2, y2) != 1) {
817 impossible("worm_cross checking for non-adjacent location?");
820 /* attempting to pass between worm segs is only relevant for diagonal */
821 if (x1 == x2 || y1 == y2)
824 /* is the same monster at <x1,y2> and at <x2,y1>? */
826 if (!worm || m_at(x2, y1) != worm)
829 /* same monster is at both adjacent spots, so must be a worm; we need
830 to figure out if the two spots are occupied by consecutive segments */
831 for (curr = wtails[worm->wormno]; curr; curr = wnxt) {
834 break; /* no next segment; can't continue */
836 /* we don't know which of <x1,y2> or <x2,y1> we'll hit first, but
837 whichever it is, they're consecutive iff next seg is the other */
838 if (curr->wx == x1 && curr->wy == y2)
839 return (boolean) (wnxt->wx == x2 && wnxt->wy == y1);
840 if (curr->wx == x2 && curr->wy == y1)
841 return (boolean) (wnxt->wx == x1 && wnxt->wy == y2);
843 /* should never reach here... */
847 /* construct an index number for a worm tail segment */
855 if (worm && worm->wormno && m_at(x, y) == worm) {
858 xchar wx = (xchar) x, wy = (xchar) y;
860 for (i = 0, curr = wtails[worm->wormno]; curr; curr = curr->nseg) {
861 if (curr->wx == wx && curr->wy == wy)
865 for (n = i; curr; curr = curr->nseg)