Example #1
0
/*
 *  worm_nomove()
 *
 *  Check for mon->wormno before calling this function!
 *
 *  The worm don't move so it should shrink.
 */
void worm_nomove(struct monst *worm)
{
    shrink_worm((int) worm->wormno);	/* shrink */

    if (worm->mhp > 3)
	worm->mhp -= 3;		/* mhpmax not changed ! */
    else
	worm->mhp = 1;
}
Example #2
0
/*
 *  worm_move()
 *
 *  Check for mon->wormno before calling this function!
 *
 *  Move the worm.  Maybe grow.
 */
void
worm_move(struct monst *worm)
{
    struct wseg *seg, *new_seg; /* new segment */
    int wnum = worm->wormno;    /* worm number */


/*  if (!wnum) return;  bullet proofing */

    /* 
     *  Place a segment at the old worm head.  The head has already moved.
     */
    seg = level->wheads[wnum];
    place_worm_seg(worm, seg->wx, seg->wy);
    newsym(seg->wx, seg->wy);   /* display the new segment */

    /* 
     *  Create a new dummy segment head and place it at the end of the list.
     */
    new_seg = malloc(sizeof (struct wseg));
    new_seg->wx = worm->mx;
    new_seg->wy = worm->my;
    new_seg->nseg = NULL;
    seg->nseg = new_seg;        /* attach it to the end of the list */
    level->wheads[wnum] = new_seg;      /* move the end pointer */


    if (level->wgrowtime[wnum] <= moves) {
        if (!level->wgrowtime[wnum])
            level->wgrowtime[wnum] = moves + rnd(5);
        else
            level->wgrowtime[wnum] += rn1(15, 3);
        worm->mhp += 3;
        if (worm->mhp > MHPMAX)
            worm->mhp = MHPMAX;
        if (worm->mhp > worm->mhpmax)
            worm->mhpmax = worm->mhp;
    } else
        /* The worm doesn't grow, so the last segment goes away. */
        shrink_worm(wnum);
}
Example #3
0
/*  cutworm()
 *
 *  Check for mon->wormno before calling this function!
 *
 *  When hitting a worm (worm) at position x, y, with a weapon (weap),
 *  there is a chance that the worm will be cut in half, and a chance
 *  that both halves will survive.
 */
void
cutworm(struct monst *worm, xchar x, xchar y, struct obj *weap)
{
    struct wseg *curr, *new_tail;
    struct monst *new_worm;
    int wnum = worm->wormno;
    int cut_chance, new_wnum;

    if (!wnum)
        return; /* bullet proofing */

    if (x == worm->mx && y == worm->my)
        return; /* hit on head */

    /* cutting goes best with a bladed weapon */
    cut_chance = rnd(20);       /* Normally 1-16 does not cut */
    /* Normally 17-20 does */

    if (weap && objects[weap->otyp].oc_dir & SLASH)
        cut_chance += 10;       /* With a slashing weapon 1- 6 does not cut */
    /* 7-20 does */

    if (cut_chance < 17)
        return; /* not good enough */

    /* Find the segment that was attacked. */
    curr = level->wtails[wnum];

    while ((curr->wx != x) || (curr->wy != y)) {
        curr = curr->nseg;
        if (!curr) {
            impossible("cutworm: no segment at (%d,%d)", (int)x, (int)y);
            return;
        }
    }

    /* If this is the tail segment, then the worm just loses it. */
    if (curr == level->wtails[wnum]) {
        shrink_worm(wnum);
        return;
    }

    /* 
     *  Split the worm.  The tail for the new worm is the old worm's tail.
     *  The tail for the old worm is the segment that follows "curr",
     *  and "curr" becomes the dummy segment under the new head.
     */
    new_tail = level->wtails[wnum];
    level->wtails[wnum] = curr->nseg;
    curr->nseg = NULL;  /* split the worm */

    /* 
     *  At this point, the old worm is correct.  Any new worm will have
     *  it's head at "curr" and its tail at "new_tail".
     */

    /* Sometimes the tail end dies. */
    if (rn2(3) || !(new_wnum = get_wormno(level)) || !worm->m_lev) {
        cutoff(worm, new_tail);
        return;
    }

    remove_monster(level, x, y);        /* clone_mon puts new head here */
    if (!(new_worm = clone_mon(worm, x, y))) {
        cutoff(worm, new_tail);
        return;
    }
    new_worm->wormno = new_wnum;        /* affix new worm number */

    /* Devalue the monster level of both halves of the worm. */
    worm->m_lev =
        ((unsigned)worm->m_lev <=
         3) ? (unsigned)worm->m_lev : max((unsigned)worm->m_lev - 2, 3);
    new_worm->m_lev = worm->m_lev;

    /* Calculate the mhp on the new_worm for the (lower) monster level. */
    new_worm->mhpmax = new_worm->mhp = dice((int)new_worm->m_lev, 8);

    /* Calculate the mhp on the old worm for the (lower) monster level. */
    if (worm->m_lev > 3) {
        worm->mhpmax = dice((int)worm->m_lev, 8);
        if (worm->mhpmax < worm->mhp)
            worm->mhp = worm->mhpmax;
    }

    level->wtails[new_wnum] = new_tail; /* We've got all the info right now */
    level->wheads[new_wnum] = curr;     /* so we can do this faster than */
    level->wgrowtime[new_wnum] = 0L;    /* trying to call initworm().  */

    /* Place the new monster at all the segment locations. */
    place_wsegs(new_worm);

    if (flags.mon_moving)
        pline(msgc_monneutral, "%s is cut in half.", Monnam(worm));
    else
        pline(msgc_combatgood, "You cut %s in half.", mon_nam(worm));
}