1 /* NetHack 3.6 worm.c $NHDT-Date: 1446887540 2015/11/07 09:12:20 $ $NHDT-Branch: master $:$NHDT-Revision: 1.19 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
5 /* JNetHack Copyright */
6 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
7 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016 */
8 /* JNetHack may be freely redistributed. See license for details. */
13 #define newseg() (struct wseg *) alloc(sizeof (struct wseg))
14 #define dealloc_seg(wseg) free((genericptr_t) (wseg))
16 /* worm segment structure */
19 xchar wx, wy; /* the segment's position */
22 STATIC_DCL void FDECL(toss_wsegs, (struct wseg *, BOOLEAN_P));
23 STATIC_DCL void FDECL(shrink_worm, (int));
24 STATIC_DCL void FDECL(random_dir, (XCHAR_P, XCHAR_P, xchar *, xchar *));
25 STATIC_DCL struct wseg *FDECL(create_worm_tail, (int));
27 /* Description of long worm implementation.
29 * Each monst struct of the head of a tailed worm has a wormno set to
30 * 1 <= wormno < MAX_NUM_WORMS
31 * If wormno == 0 this does not mean that the monster is not a worm,
32 * it just means that the monster does not have a long worm tail.
34 * The actual segments of a worm are not full blown monst structs.
35 * They are small wseg structs, and their position in the levels.monsters[][]
36 * array is held by the monst struct of the head of the worm. This makes
37 * things like probing and hit point bookkeeping much easier.
39 * The segments of the long worms on a level are kept as an array of
40 * singly threaded linked lists. The wormno variable is used as an index
41 * for these segment arrays.
43 * wtails: The first (starting struct) of a linked list. This points
44 * to the tail (last) segment of the worm.
46 * wheads: The last (end) of a linked list of segments. This points to
47 * the segment that is at the same position as the real monster
48 * (the head). Note that the segment that wheads[wormno] points
49 * to, is not displayed. It is simply there to keep track of
50 * where the head came from, so that worm movement and display
51 * are simplified later.
52 * Keeping the head segment of the worm at the end of the list
53 * of tail segments is an endless source of confusion, but it is
55 * From now on, we will use "start" and "end" to refer to the
56 * linked list and "head" and "tail" to refer to the worm.
58 * One final worm array is:
60 * wgrowtime: This tells us when to add another segment to the worm.
62 * When a worm is moved, we add a new segment at the head, and delete the
63 * segment at the tail (unless we want it to grow). This new head segment is
64 * located in the same square as the actual head of the worm. If we want
65 * to grow the worm, we don't delete the tail segment, and we give the worm
66 * extra hit points, which possibly go into its maximum.
68 * Non-moving worms (worm_nomove) are assumed to be surrounded by their own
69 * tail, and, thus, shrink instead of grow (as their tails keep going while
70 * their heads are stopped short). In this case, we delete the last tail
71 * segment, and remove hit points from the worm.
74 struct wseg *wheads[MAX_NUM_WORMS] = DUMMY, *wtails[MAX_NUM_WORMS] = DUMMY;
75 long wgrowtime[MAX_NUM_WORMS] = DUMMY;
80 * Find an unused worm tail slot and return the index. A zero means that
81 * there are no slots available. This means that the worm head can exist,
82 * it just cannot ever grow a tail.
84 * It, also, means that there is an optimisation to made. The [0] positions
85 * of the arrays are never used. Meaning, we really *could* have one more
86 * tailed worm on the level, or use a smaller array (using wormno - 1).
88 * Implementation is left to the interested hacker.
93 register int new_wormno = 1;
95 while (new_wormno < MAX_NUM_WORMS) {
96 if (!wheads[new_wormno])
97 return new_wormno; /* found an empty wtails[] slot at new_wormno
102 return 0; /* level infested with worms */
108 * Use if (mon->wormno = get_wormno()) before calling this function!
110 * Initialize the worm entry. This will set up the worm grow time, and
111 * create and initialize the dummy segment for wheads[] and wtails[].
113 * If the worm has no tail (ie get_wormno() fails) then this function need
117 initworm(worm, wseg_count)
121 register struct wseg *seg, *new_tail = create_worm_tail(wseg_count);
122 register int wnum = worm->wormno;
124 /* if (!wnum) return; bullet proofing */
127 wtails[wnum] = new_tail;
128 for (seg = new_tail; seg->nseg; seg = seg->nseg)
132 wtails[wnum] = wheads[wnum] = seg = newseg();
133 seg->nseg = (struct wseg *) 0;
137 wgrowtime[wnum] = 0L;
143 * Get rid of all worm segments on and following the given pointer curr.
144 * The display may or may not need to be updated as we free the segments.
148 toss_wsegs(curr, display_update)
149 register struct wseg *curr;
150 register boolean display_update;
152 register struct wseg *seg;
157 /* remove from level.monsters[][] */
159 /* need to check curr->wx for genocided while migrating_mon */
161 remove_monster(curr->wx, curr->wy);
163 /* update screen before deallocation */
165 newsym(curr->wx, curr->wy);
168 /* free memory used by the segment */
177 * Remove the tail segment of the worm (the starting segment of the list).
182 int wnum; /* worm number */
186 if (wtails[wnum] == wheads[wnum])
187 return; /* no tail */
190 wtails[wnum] = seg->nseg;
191 seg->nseg = (struct wseg *) 0;
192 toss_wsegs(seg, TRUE);
198 * Check for mon->wormno before calling this function!
200 * Move the worm. Maybe grow.
206 register struct wseg *seg, *new_seg; /* new segment */
207 register int wnum = worm->wormno; /* worm number */
209 /* if (!wnum) return; bullet proofing */
212 * Place a segment at the old worm head. The head has already moved.
215 place_worm_seg(worm, seg->wx, seg->wy);
216 newsym(seg->wx, seg->wy); /* display the new segment */
219 * Create a new dummy segment head and place it at the end of the list.
222 new_seg->wx = worm->mx;
223 new_seg->wy = worm->my;
224 new_seg->nseg = (struct wseg *) 0;
225 seg->nseg = new_seg; /* attach it to the end of the list */
226 wheads[wnum] = new_seg; /* move the end pointer */
228 if (wgrowtime[wnum] <= moves) {
229 if (!wgrowtime[wnum])
230 wgrowtime[wnum] = moves + rnd(5);
232 wgrowtime[wnum] += rn1(15, 3);
234 if (worm->mhp > MHPMAX)
236 if (worm->mhp > worm->mhpmax)
237 worm->mhpmax = worm->mhp;
239 /* The worm doesn't grow, so the last segment goes away. */
246 * Check for mon->wormno before calling this function!
248 * The worm don't move so it should shrink.
252 register struct monst *worm;
254 shrink_worm((int) worm->wormno); /* shrink */
257 worm->mhp -= 3; /* mhpmax not changed ! */
265 * Check for mon->wormno before calling this function!
271 register struct monst *worm;
273 register int wnum = worm->wormno;
275 /* if (!wnum) return; bullet proofing */
279 /* This will also remove the real monster (ie 'w') from the its
280 * position in level.monsters[][].
282 toss_wsegs(wtails[wnum], TRUE);
284 wheads[wnum] = wtails[wnum] = (struct wseg *) 0;
290 * Check for mon->wormno before calling this function!
292 * If the hero is near any part of the worm, the worm will try to attack.
296 register struct monst *worm;
298 register int wnum = worm->wormno;
299 register struct wseg *seg;
301 /* if (!wnum) return; bullet proofing */
303 /* This does not work right now because mattacku() thinks that the head
305 * out of range of the player. We might try to kludge, and bring the
307 * within range for a tiny moment, but this needs a bit more looking at
308 * before we decide to do this.
310 for (seg = wtails[wnum]; seg; seg = seg->nseg)
311 if (distu(seg->wx, seg->wy) < 3)
312 (void) mattacku(worm);
317 * Check for mon->wormno before calling this function!
319 * When hitting a worm (worm) at position x, y, with a weapon (weap),
320 * there is a chance that the worm will be cut in half, and a chance
321 * that both halves will survive.
324 cutworm(worm, x, y, weap)
329 register struct wseg *curr, *new_tail;
330 register struct monst *new_worm;
331 int wnum = worm->wormno;
332 int cut_chance, new_wnum;
335 return; /* bullet proofing */
337 if (x == worm->mx && y == worm->my)
338 return; /* hit on head */
340 /* cutting goes best with a bladed weapon */
341 cut_chance = rnd(20); /* Normally 1-16 does not cut */
342 /* Normally 17-20 does */
344 if (weap && is_blade(weap)) /* With a blade 1- 6 does not cut */
345 cut_chance += 10; /* 7-20 does */
348 return; /* not good enough */
350 /* Find the segment that was attacked. */
353 while ((curr->wx != x) || (curr->wy != y)) {
356 impossible("cutworm: no segment at (%d,%d)", (int) x, (int) y);
361 /* If this is the tail segment, then the worm just loses it. */
362 if (curr == wtails[wnum]) {
368 * Split the worm. The tail for the new worm is the old worm's tail.
369 * The tail for the old worm is the segment that follows "curr",
370 * and "curr" becomes the dummy segment under the new head.
372 new_tail = wtails[wnum];
373 wtails[wnum] = curr->nseg;
374 curr->nseg = (struct wseg *) 0; /* split the worm */
377 * At this point, the old worm is correct. Any new worm will have
378 * it's head at "curr" and its tail at "new_tail". The old worm
379 * must be at least level 3 in order to produce a new worm.
383 new_wnum = (worm->m_lev >= 3 && !rn2(3)) ? get_wormno() : 0;
385 remove_monster(x, y); /* clone_mon puts new head here */
386 /* clone_mon() will fail if enough long worms have been
387 created to have them be marked as extinct or if the hit
388 that cut the current one has dropped it down to 1 HP */
389 new_worm = clone_mon(worm, x, y);
392 /* Sometimes the tail end dies. */
394 if (context.mon_moving) {
395 if (canspotmon(worm))
397 pline("Part of %s tail has been cut off.",
398 s_suffix(mon_nam(worm)));
400 pline("%s
\82Ì
\90K
\94ö
\82Ì
\88ê
\95\94\95ª
\82ª
\90Ø
\82è
\97\8e\82Æ
\82³
\82ê
\82½
\81D",
405 You("cut part of the tail off of %s.", mon_nam(worm));
407 You("%s
\82Ì
\90K
\94ö
\82Ì
\88ê
\95\94\95ª
\82ð
\90Ø
\82Á
\82½
\81D", mon_nam(worm));
408 toss_wsegs(new_tail, TRUE);
414 new_worm->wormno = new_wnum; /* affix new worm number */
415 new_worm->mcloned = 0; /* treat second worm as a normal monster */
417 /* Devalue the monster level of both halves of the worm.
418 Note: m_lev is always at least 3 in order to get this far. */
419 worm->m_lev = max((unsigned) worm->m_lev - 2, 3);
420 new_worm->m_lev = worm->m_lev;
422 /* Calculate the lower-level mhp; use <N>d8 for long worms.
423 Can't use newmonhp() here because it would reset m_lev. */
424 new_worm->mhpmax = new_worm->mhp = d((int) new_worm->m_lev, 8);
425 worm->mhpmax = d((int) worm->m_lev, 8); /* new maxHP for old worm */
426 if (worm->mhpmax < worm->mhp)
427 worm->mhp = worm->mhpmax;
429 wtails[new_wnum] = new_tail; /* We've got all the info right now */
430 wheads[new_wnum] = curr; /* so we can do this faster than */
431 wgrowtime[new_wnum] = 0L; /* trying to call initworm(). */
433 /* Place the new monster at all the segment locations. */
434 place_wsegs(new_worm);
436 if (context.mon_moving)
438 pline("%s is cut in half.", Monnam(worm));
440 pline("%s
\82Í
\90^
\82Á
\82Õ
\82½
\82Â
\82É
\82³
\82ê
\82½
\81D", Monnam(worm));
443 You("cut %s in half.", mon_nam(worm));
445 You("%s
\82ð
\90^
\82Á
\82Õ
\82½
\82Â
\82É
\82µ
\82½
\81D", mon_nam(worm));
451 * Refresh all of the segments of the given worm. This is only called
452 * from see_monster() in display.c or when a monster goes minvis. It
453 * is located here for modularity.
459 struct wseg *curr = wtails[worm->wormno];
461 /* if (!mtmp->wormno) return; bullet proofing */
463 while (curr != wheads[worm->wormno]) {
464 newsym(curr->wx, curr->wy);
472 * Display all of the segments of the given worm for detection.
475 detect_wsegs(worm, use_detection_glyph)
477 boolean use_detection_glyph;
480 struct wseg *curr = wtails[worm->wormno];
482 /* if (!mtmp->wormno) return; bullet proofing */
484 while (curr != wheads[worm->wormno]) {
485 num = use_detection_glyph
486 ? detected_monnum_to_glyph(what_mon(PM_LONG_WORM_TAIL))
488 ? petnum_to_glyph(what_mon(PM_LONG_WORM_TAIL))
489 : monnum_to_glyph(what_mon(PM_LONG_WORM_TAIL)));
490 show_glyph(curr->wx, curr->wy, num);
498 * Save the worm information for later use. The count is the number
499 * of segments, including the dummy. Called from save.c.
507 struct wseg *curr, *temp;
509 if (perform_bwrite(mode)) {
510 for (i = 1; i < MAX_NUM_WORMS; i++) {
511 for (count = 0, curr = wtails[i]; curr; curr = curr->nseg)
513 /* Save number of segments */
514 bwrite(fd, (genericptr_t) &count, sizeof(int));
515 /* Save segment locations of the monster. */
517 for (curr = wtails[i]; curr; curr = curr->nseg) {
518 bwrite(fd, (genericptr_t) & (curr->wx), sizeof(xchar));
519 bwrite(fd, (genericptr_t) & (curr->wy), sizeof(xchar));
523 bwrite(fd, (genericptr_t) wgrowtime, sizeof(wgrowtime));
526 if (release_data(mode)) {
527 /* Free the segments only. savemonchn() will take care of the
529 for (i = 1; i < MAX_NUM_WORMS; i++) {
530 if (!(curr = wtails[i]))
535 dealloc_seg(curr); /* free the segment */
538 wheads[i] = wtails[i] = (struct wseg *) 0;
546 * Restore the worm information from the save file. Called from restore.c
553 struct wseg *curr, *temp;
555 for (i = 1; i < MAX_NUM_WORMS; i++) {
556 mread(fd, (genericptr_t) &count, sizeof(int));
560 /* Get the segments. */
561 for (curr = (struct wseg *) 0, j = 0; j < count; j++) {
563 temp->nseg = (struct wseg *) 0;
564 mread(fd, (genericptr_t) & (temp->wx), sizeof(xchar));
565 mread(fd, (genericptr_t) & (temp->wy), sizeof(xchar));
574 mread(fd, (genericptr_t) wgrowtime, sizeof(wgrowtime));
580 * Place the segments of the given worm. Called from restore.c
586 struct wseg *curr = wtails[worm->wormno];
588 /* if (!mtmp->wormno) return; bullet proofing */
590 while (curr != wheads[worm->wormno]) {
591 place_worm_seg(worm, curr->wx, curr->wy);
599 * This function is equivalent to the remove_monster #define in
600 * rm.h, only it will take the worm *and* tail out of the levels array.
601 * It does not get rid of (dealloc) the worm tail structures, and it does
602 * not remove the mon from the fmon chain.
606 register struct monst *worm;
608 register struct wseg *curr = wtails[worm->wormno];
610 /* if (!mtmp->wormno) return; bullet proofing */
613 remove_monster(curr->wx, curr->wy);
614 newsym(curr->wx, curr->wy);
620 * place_worm_tail_randomly()
622 * Place a worm tail somewhere on a level behind the head.
623 * This routine essentially reverses the order of the wsegs from head
624 * to tail while placing them.
625 * x, and y are most likely the worm->mx, and worm->my, but don't *need* to
626 * be, if somehow the head is disjoint from the tail.
629 place_worm_tail_randomly(worm, x, y)
633 int wnum = worm->wormno;
634 struct wseg *curr = wtails[wnum];
635 struct wseg *new_tail;
636 register xchar ox = x, oy = y;
638 /* if (!wnum) return; bullet proofing */
640 if (wnum && (!wtails[wnum] || !wheads[wnum])) {
641 impossible("place_worm_tail_randomly: wormno is set without a tail!");
645 wheads[wnum] = new_tail = curr;
647 new_tail->nseg = (struct wseg *) 0;
655 /* pick a random direction from x, y and search for goodpos() */
658 random_dir(ox, oy, &nx, &ny);
659 } while (!goodpos(nx, ny, worm, 0) && (tryct++ < 50));
662 place_worm_seg(worm, nx, ny);
667 wtails[wnum]->nseg = new_tail;
668 new_tail = wtails[wnum];
670 } else { /* Oops. Truncate because there was */
671 toss_wsegs(curr, FALSE); /* no place for the rest of it */
672 curr = (struct wseg *) 0;
678 * Given a coordinate x, y.
679 * return in *nx, *ny, the coordinates of one of the <= 8 squares adjoining.
681 * This function, and the loop it serves, could be eliminated by coding
682 * enexto() with a search radius.
686 random_dir(x, y, nx, ny)
688 register xchar *nx, *ny;
693 *nx += (x > 1 /* extreme left ? */
694 ? (x < COLNO /* extreme right ? */
695 ? (rn2(3) - 1) /* neither so +1, 0, or -1 */
696 : -rn2(2)) /* 0, or -1 */
697 : rn2(2)); /* 0, or 1 */
699 *ny += (*nx == x /* same kind of thing with y */
700 ? (y > 1 ? (y < ROWNO ? (rn2(2) ? 1 : -1) : -1) : 1)
701 : (y > 1 ? (y < ROWNO ? (rn2(3) - 1) : -rn2(2)) : rn2(2)));
705 * returns the number of visible segments that a worm has.
712 register struct wseg *curr = (wtails[mtmp->wormno])->nseg;
714 /* if (!mtmp->wormno) return 0; bullet proofing */
724 /* create_worm_tail()
725 * will create a worm tail chain of (num_segs + 1) and return pointer to it.
729 create_worm_tail(num_segs)
733 register struct wseg *new_tail, *curr;
736 return (struct wseg *) 0;
738 new_tail = curr = newseg();
739 curr->nseg = (struct wseg *) 0;
743 while (i < num_segs) {
744 curr->nseg = newseg();
746 curr->nseg = (struct wseg *) 0;
756 * Is any segment of this worm in viewing range? Note: caller must check
757 * invisibility and telepathy (which should only show the head anyway).
758 * Mostly used in the canseemon() macro.
764 struct wseg *curr = wtails[worm->wormno];
767 if (cansee(curr->wx, curr->wy))
774 /* would moving from <x1,y1> to <x2,y2> involve passing between two
775 consecutive segments of the same worm? */
777 worm_cross(x1, y1, x2, y2)
781 struct wseg *curr, *wnxt;
784 * With digits representing relative sequence number of the segments,
785 * returns true when testing between @ and ? (passes through worm's
786 * body), false between @ and ! (stays on same side of worm).
793 if (distmin(x1, y1, x2, y2) != 1) {
794 impossible("worm_cross checking for non-adjacent location?");
797 /* attempting to pass between worm segs is only relevant for diagonal */
798 if (x1 == x2 || y1 == y2)
801 /* is the same monster at <x1,y2> and at <x2,y1>? */
803 if (!worm || m_at(x2, y1) != worm)
806 /* same monster is at both adjacent spots, so must be a worm; we need
807 to figure out if the two spots are occupied by consecutive segments */
808 for (curr = wtails[worm->wormno]; curr; curr = wnxt) {
811 break; /* no next segment; can't continue */
813 /* we don't know which of <x1,y2> or <x2,y1> we'll hit first, but
814 whichever it is, they're consecutive iff next seg is the other */
815 if (curr->wx == x1 && curr->wy == y2)
816 return (boolean) (wnxt->wx == x2 && wnxt->wy == y1);
817 if (curr->wx == x2 && curr->wy == y1)
818 return (boolean) (wnxt->wx == x1 && wnxt->wy == y2);
820 /* should never reach here... */